Denise Mauldin
Denise Mauldin

Reputation: 5615

PyQt5 reusable file selection dialog

I want to load two files using the GUI and then execute a python command on the two files. I want to use a reusable file select method that sets the element that it was called on. Every tutorial that I see sets a specific named element instead of taking an element. How do I fix this code?

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QDesktopWidget, QLabel, QPushButton, QInputDialog, QLineEdit, QFileDialog, QAction
from PyQt5.QtGui import QIcon


class dswfGui(QMainWindow):

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

    def initUI(self):
        # Build the window widget
        self.setGeometry(300, 300, 550, 550)  # x, y, w, h
        self.setWindowTitle("workflow")
        self.center()

        # Add a label
        label = QLabel("workflow", self)
        label.resize(label.sizeHint())
        label.move(120, 20)

        # Select input file1
        file1_label = QLabel("file 1", self)
        file1_label.resize(file1_label.sizeHint())
        file1_label.move(20,50)
        file1_label.setToolTip('end file 1')
        self.file1 = QLineEdit("Select file", self)
        self.file1.setObjectName("file1")
        self.file1.resize(self.file1.sizeHint())
        self.file1.move(120, 50)
        self.file1.setToolTip('Select file 1')
        f1btn = QPushButton('Select file 1', self)
        f1btn.resize(f1btn.sizeHint())
        f1btn.element = self.file1
        f1btn.move(250, 46)
        f1btn.clicked.connect(self.selectFile)

        # Select input file2
        file2_label = QLabel("file 2", self)
        file2_label.resize(file2_label.sizeHint())
        file2_label.move(20,90)
        file2_label.setToolTip('end file 2')
        self.file2 = QLineEdit("Select file2", self)
        self.file2.setObjectName("file2")
        self.file2.resize(self.file2.sizeHint())
        self.file2.move(120, 90)
        self.file2.setToolTip('Select file 2')
        f2btn = QPushButton('Select file 2', self)
        f2btn.resize(f2btn.sizeHint())
        f2btn.element = self.file1
        f2btn.move(250, 86)
        # this doesn't work because self.selectFile doesn't accept an element or read an element
        f2btn.clicked.connect(self.selectFile)

        self.statusBar()

        # Show window and run
        self.show()

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def selectFile(self):
        # I want this to be reusable, but it doesn't seem
        # to want to let me pass element in or call self.element
        self.element.setText(QFileDialog.getOpenFileName()[0])
        #this works but is not DRY
        #self.file1.setText(QFileDialog.getOpenFileName()[0])

if __name__ == "__main__":
    app = QApplication(sys.argv)
    gui = dswfGui()
    sys.exit(app.exec_())

I'm not sure how to make what I want clearer. I want to select two files in the UI. I want to use one method (selectFile) to open the QFileDialog and set the appropriate QLineEdit to the selected value. I don't want to have a QFileDialog for each QLineEdit because that's not DRY.

Upvotes: 1

Views: 2015

Answers (1)

Ceppo93
Ceppo93

Reputation: 1046

The question is not very clear, anyway if I understand correctly you have the following options:

Use lambda(s):

This can became nasty if you need to disconnect single functions

f1btn.clicked.connect(lambda: self.selectFile(self.file1))
f2btn.clicked.connect(lambda: self.selectFile(self.file2))

Define two callbacks functions

This is almost the same as what you're trying to avoid

def file1_select(self):
    self.selectFile(self, self.file1)

def file2_select(self):
    self.selectFile(self, self.file2)

Upvotes: 1

Related Questions