0

Sorry for the long post but wished to give as much as poss

There is a lot of code not shown here but I'm trying to clean up a huge function of buttons in a PyQt5 Gui

I have a GUI output and all is working well and I'm now making an attempt to remove the repeated code and so creating a function to create the buttons.

In a functioned name initUI I have around 20 buttons. As can be seen from the code, the old way was creating each one separately.

What I have done is to create a function that the parameters are sent to and this then creates them.

This does work apart from defRun arg sent to button. This is passing a call to another function I've highlighted with >>>>arg<<<< this isn't really in the code

class iac2tf(QMainWindow):
    def __init__(self):
        super(iac2tf, self).__init__()
        self.initUI()
        self.setGeometry(0, 0, 1700, 1000)........

     def button (self, buttonName, buttonText, >>>>defRun<<<<, buttonWidth, buttonHeight, buttonx, buttony):
            self.buttonName = QtWidgets.QPushButton(buttonText,self)
        >>>>self.buttonName.clicked.connect(lambda:self.defRun)<<<<
            self.buttonName.resize(buttonWidth,buttonHeight)
            self.buttonName.move(buttonx,buttony)   
            self.buttonName.show()

    def initUI(self): 
            #passed style
            self.openFilebutton = self.button('openFile', 'Open File', >>>'open()'<<<< ,110,30,5,50)

            #Old style
            self.ProcessFile = QtWidgets.QPushButton('Process File',self)
            self.ProcessFile.clicked.connect(self.processFile)
            self.ProcessFile.resize(110,30)
            self.ProcessFile.move(5, 80)  


/......
   ....../


def open(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        file, _ = QFileDialog.getOpenFileNames(self, 'Ope....... 


app = QApplication(sys.argv)
win = iac2tf()
win.show()


I've tried passing Knowing some would fail but wanted to cover all bases and was exasperated

  • str(open)

GUI opens with

<built-in function open>

On clicking button

  File "/home/bob/present/proj/WorksArea/gui.py", line 38, in <lambda>
    self.buttonName.clicked.connect(lambda:self.defRun)
AttributeError: 'iac2tf' object has no attribute 'defRun'

  • str(open())
self.openFilebutton = self.button('openFile', 'Open File', str(open()) ,110,30,5,50)
TypeError: Required argument 'file' (pos 1) not found


  • str(self.open)

GUI opens with

<bound method iac2tf.open of <__main__.iac2tf object at 0x7f87e73da948>>

On clicking button

Traceback (most recent call last):
  File "/home/bob/present/proj/WorksArea/gui.py", line 38, in <lambda>
    self.buttonName.clicked.connect(lambda:self.defRun)
AttributeError: 'iac2tf' object has no attribute 'defRun'

  • str(self.open())

Open file selection menu ie starts open func


  • self.open

GUI starts

<bound method iac2tf.open of <__main__.iac2tf object at 0x7fdcb2dee948>>

On clicking button

Traceback (most recent call last):
  File "/home/bob/present/proj/WorksArea/gui.py", line 38, in <lambda>
    self.buttonName.clicked.connect(lambda:self.defRun)
AttributeError: 'iac2tf' object has no attribute 'defRun'

  • 'self.open'
  • 'self.open()'
  • 'open()'
  • 'open'

opens GUI without error

on clicking button

Traceback (most recent call last):
  File "/home/bob/present/proj/WorksArea/gui.py", line 38, in <lambda>
    self.buttonName.clicked.connect(lambda:self.defRun)
AttributeError: 'iac2tf' object has no attribute 'defRun'

  • open

opens GUI with

   <built-in function open>

on clicking button

 Traceback (most recent call last):
  File "/home/bob/present/proj/WorksArea/gui.py", line 38, in <lambda>
    self.buttonName.clicked.connect(lambda:self.defRun)
AttributeError: 'iac2tf' object has no attribute 'defRun'

  • open()
self.openFilebutton = self.button('openFile', 'Open File', open() ,110,30,5,50)
TypeError: Required argument 'file' (pos 1) not found

  • passing to a local to func var all of above but is as is :(
5
  • provide a minimal reproducible example Commented Feb 21, 2020 at 1:11
  • Ok thanks, will do tomorrow thx Commented Feb 21, 2020 at 1:51
  • try with: self.buttonName.clicked.connect(defRun) and self.openFilebutton = self.button('openFile', 'Open File', self.open, 110,30,5,50) Commented Feb 21, 2020 at 1:55
  • Cheers, will do. Are you thinking lambda tripping up? Could you explain (I'm learning) Commented Feb 21, 2020 at 1:57
  • What I indicate is a presumption since the code you provide does not give me the necessary guarantee that it works correctly, so I will expect you to provide the information I have asked you to give more details. Commented Feb 21, 2020 at 2:02

1 Answer 1

1

Here is an example of passing functions as arguments.

class Template(QWidget):

    def __init__(self):
        super().__init__()
        self.vbox = QVBoxLayout(self)
        self.create_button('Open', self.open)
        self.create_button('Close', self.close)

    def create_button(self, text, slot):
        btn = QPushButton(text)
        btn.clicked.connect(slot)
        self.vbox.addWidget(btn)

    def open(self):
        QFileDialog.getOpenFileName(self)

Also worth noting that the arg buttonName is never actually used in this function:

def button (self, buttonName, buttonText, >>>>defRun<<<<, buttonWidth, buttonHeight, buttonx, buttony):
    self.buttonName = QtWidgets.QPushButton(buttonText,self)
    . . .

That variable only exists in the local scope of the function, and self.buttonName refers to another object entirely. That is to say, if you wanted to refer to a button you created where you passed 'openFile' for the buttonName arg, it would not be called self.openFile, it would be called literally self.buttonName. You could however, use exec() to achieve this, although it is generally discouraged.

Sign up to request clarification or add additional context in comments.

2 Comments

Cheers I'll give it a bash. That may be a big issue. I was assuming that the button would be named as openFile
Just looking through my errors, it actually say buttonName.... Feeling silly now 🙄. I wasn't seeing the wood for the trees. As said thanks and ill get to try it and report back

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.