Добавьте правильный FileDialog с Browse PushButton в PyQt5 - PullRequest
1 голос
/ 05 марта 2020

Я написал следующий код для выполнения некоторых вычислений. Я хочу добавить виджет, такой как маленькая картинка, чтобы при нажатии на кнопку я мог просматривать файл CSV, и этот путь показывался в LineEdite. Мне нужно иметь этот виджет в QGroupBox информации об эксперименте под флажком. Но я не знаю, как добавить все эти 3 виджета в одну строку в этом групповом окне.

import sys
from PyQt5.QtWidgets import QMainWindow, QAction, QMenu, QApplication
from PyQt5 import QtGui, QtCore
from PyQt5 import QtWidgets

class Application(QMainWindow):

    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('File')
        run = menubar.addMenu('Run')
        exit = menubar.addMenu('Exit')

        impMenu = QMenu('Import', self)
        impAct = QAction('Import mail', self)
        impMenu.addAction(impAct)

        newAct = QAction('New', self)

        fileMenu.addAction(newAct)
        fileMenu.addMenu(impMenu)

        # ------------- Layout ---------------------------
        wid =QtWidgets.QWidget(self)
        self.setCentralWidget(wid)
        mainLayout = QtWidgets.QVBoxLayout()

        config_box = QtWidgets.QGroupBox("Configuration")
        info_box = QtWidgets.QGroupBox("Info Box")

        # ------------- Config Box Layut -----------------
        Config_Box_Layout = QtWidgets.QGridLayout()


        case_box = QtWidgets.QGroupBox("case")

        operations_box = QtWidgets.QGroupBox("Operations")

        Config_Box_Layout.addWidget(case_box, 0, 0)
        Config_Box_Layout.addWidget(operations_box, 0, 1)

        # ----------- Operations-----------------------
        operation_layout = QtWidgets.QVBoxLayout()

        op1 = QtWidgets.QCheckBox('Add')
        op2= QtWidgets.QCheckBox('Multiplication')

        operation_layout.addWidget(op1)
        operation_layout.addWidget(op2)
        # ----------- cases -----------------------
        case_layout = QtWidgets.QVBoxLayout()
        _1 = QtWidgets.QRadioButton("1")
        _2 = QtWidgets.QRadioButton("2")
        _3 = QtWidgets.QRadioButton("3")

        case_layout.addWidget(_1)
        case_layout.addWidget(_2)
        case_layout.addWidget(_3)


        # --------- Info Box LayOut -----------------------
        Info_box_layout = QtWidgets.QVBoxLayout()

        exp_input_grou = QtWidgets.QGroupBox('Experiment Info')
        exp_input_layout = QtWidgets.QVBoxLayout()

        version_input = QtWidgets.QComboBox()
        version_input.addItem("Algo Version")
        version_input.addItem("V53")
        version_input.addItem("V52")
        version_input.addItem("V4")
        version_input.addItem("V3")

        nested_folder = QtWidgets.QCheckBox('Nested Data Path')

        dialog_file = QtWidgets.QFileDialog()

        pushB_ = QtWidgets.QPushButton('Browse')

        exp_input_layout.addWidget(version_input)
        exp_input_layout.addWidget(nested_folder)
        exp_input_layout.addWidget(pushB_)
        exp_input_layout.addWidget(dialog_file)


        exp_report = QtWidgets.QTextEdit()
        progres_bar = QtWidgets.QProgressBar()


        Info_box_layout.addWidget(exp_input_grou)
        Info_box_layout.addWidget(exp_report)
        Info_box_layout.addWidget(progres_bar)

        gt_path = QtWidgets.QLineEdit()
        gt_path.setFixedWidth(100)
        # -------- Adding Layouts ------------------------
        mainLayout.addWidget(config_box)
        config_box.setLayout(Config_Box_Layout)
        case_box.setLayout(case_layout)
        operations_box.setLayout(operation_layout)
        info_box.setLayout(Info_box_layout)
        exp_input_grou.setLayout(exp_input_layout)

        mainLayout.addWidget(info_box)
        wid.setLayout(mainLayout)

        self.setGeometry(300, 300, 300, 700)
        self.setWindowTitle('Example')
        app_icon = QtGui.QIcon()
        app_icon.addFile('pic.jpg', QtCore.QSize(256, 256))
        self.setWindowIcon(app_icon)
        self.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Application()
    sys.exit(app.exec_())

enter image description here enter image description here

Ответы [ 2 ]

2 голосов
/ 05 марта 2020

Код ниже будет делать то, что вы хотите, вам просто нужно внедрить его в ваш код:

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(387, 224)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")

        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setObjectName("lineEdit")
        self.lineEdit.setReadOnly(True)

        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setObjectName("label")

        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setObjectName("pushButton")
        self.pushButton.clicked.connect(self.open_file)

        self.gridLayout.addWidget(self.lineEdit, 0, 1, 1, 1)
        self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
        self.gridLayout.addWidget(self.pushButton, 0, 2, 1, 1)

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 387, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(_translate("MainWindow", "Select output file"))
        self.pushButton.setText(_translate("MainWindow", "..."))

    def open_file(self):
        self.file_name = QtWidgets.QFileDialog.getOpenFileName(None, "Open", "", "CSV Files (*.csv)")
        if self.file_name[0] != '':
            self.lineEdit.setText(self.file_name[0])


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

Вывод:

enter image description here enter image description here enter image description here

2 голосов
/ 05 марта 2020

Если вы хотите добавить виджеты горизонтально в вертикальном макете, вы должны добавить горизонтальный макет к нему. Этот метод обычно называется «вложенными макетами».

Тогда вам не нужно создавать экземпляр диалогового окна файла в init (в противном случае он, вероятно, будет отображаться вместе с главным окном), и вы вам не нужно использовать конструктор QFileDialog() для ваших нужд, так как QDialog уже предоставляет stati c методы , которые легко позволяют вам открыть стандартный диалог и получить выбранный файл (ы) или каталог.


class Application(QMainWindow):

    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        # ...

        # --------- Info Box LayOut -----------------------
        Info_box_layout = QtWidgets.QVBoxLayout()

        exp_input_grou = QtWidgets.QGroupBox('Experiment Info')
        exp_input_layout = QtWidgets.QVBoxLayout()

        version_input = QtWidgets.QComboBox()
        version_input.addItem("Algo Version")
        version_input.addItem("V53")
        version_input.addItem("V52")
        version_input.addItem("V4")
        version_input.addItem("V3")

        nested_folder = QtWidgets.QCheckBox('Nested Data Path')

        # This should not be here!!!
        # dialog_file = QtWidgets.QFileDialog()

        exp_input_layout.addWidget(version_input)
        exp_input_layout.addWidget(nested_folder)

        <b>browse_layout = QtWidgets.QHBoxLayout()
        exp_input_layout.addLayout(browse_layout)

        self.gt_path = QtWidgets.QLineEdit()

        pushB_ = QtWidgets.QPushButton('Browse')
        pushB_.clicked.connect(self.browse_path)

        browse_layout.addWidget(self.gt_path)
        browse_layout.addWidget(pushB_)</b>

        # ...

    def browse_path(self):
        path, filter = QtWidgets.QFileDialog.getOpenFileName(self, 'Select file', 
            '', 'CSV files (*.csv);;All files (*)')
        if path:
            self.gt_path.setText(path)

QGridLayout также является допустимой альтернативой, но он не работает со всеми, так как его размеры всегда зависят от размера виджетов, содержащихся в каждой строке или столбце. Ваш случай очень прост, поэтому его можно использовать без проблем:

    def initUI(self):
        # ...

        # --------- Info Box LayOut -----------------------
        Info_box_layout = QtWidgets.QVBoxLayout()

        exp_input_grou = QtWidgets.QGroupBox('Experiment Info')
        exp_input_layout = QtWidgets.QGridLayout()

        version_input = QtWidgets.QComboBox()
        version_input.addItem("Algo Version")
        version_input.addItem("V53")
        version_input.addItem("V52")
        version_input.addItem("V4")
        version_input.addItem("V3")

        nested_folder = QtWidgets.QCheckBox('Nested Data Path')

        self.gt_path = QtWidgets.QLineEdit()
        pushB_ = QtWidgets.QPushButton('Browse')
        pushB_.clicked.connect(self.browse_path)

        # add the combobox to the first row, first column, but set its column
        # span to 2, meaning that it occupies two "columns"
        exp_input_layout.addWidget(version_input, 0, 0, 1, 2)
        # the same for the checkbox, but on the second row
        exp_input_layout.addWidget(nested_folder, 1, 0, 1, 2)
        # add the line edit, third row, first column; if you don't specify the
        # span, the widget will only occupy one "cell" of the grid layout
        exp_input_layout.addWidget(self.gt_path, 2, 0)
        # and the button, same row, second column
        exp_input_layout.addWidget(pushB_, 2, 1)

        # ...
...