Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

how to connect a def to a Qt button?, and where to put the def?



  • Hi everyone!

    this is a basic Qt template(more or less)(start by reading the comment in the code):

    import sys
    import platform
    from PySide2 import QtCore, QtGui, QtWidgets
    from PySide2.QtCore import *
    from PySide2.QtGui import (QBrush, QColor, QConicalGradient, QCursor, QFont, QFontDatabase, QIcon, QKeySequence, QLinearGradient, QPalette, QPainter, QPixmap, QRadialGradient)
    from PySide2.QtWidgets import *
    from PySide2.QtSql import (QSqlTableModel, QSqlDatabase, QSqlQuery)
    
    from ui_Main import Ui_MainWindow
    
    class MainWindow(QMainWindow):
        def __init__(self):
            QMainWindow.__init__(self)
            self.ui = Ui_MainWindow()
    
    #as I understand, here is the part where i add my code, for example:
    #-drawing the gui
    #-connecting to a database
    #-showing the database in the gui
    
    #this is what the program loads in the first run because this is the constructor...but(*)
    
            self.ui.setupUi(self)
            self.show()
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        window = MainWindow()
        sys.exit(app.exec_())
    

    (*)what i don't get is where i put the rest of the code that does not run in the first run, for example i have a do_something() module or function that runs when i click a button, where i place that? outside the constructor, but where?

    --------------------------------------------------------------------------.

    and then i have a second problem when the first its solved:

    I don't know how to write the line that links the button with the module/function

    which one is the correct?:

    self.ui.my_button.clicked.connect(do_something())
    self.ui.my_button.clicked.connect(self.do_something())
    self.ui.my_button.clicked.connect(self.a_class.do_something())
    self.ui.my_button.clicked.connect(self.an_object.do_something())
    self.ui.my_button.clicked.connect(lambda: self.an_object.do_something())
    self.ui.my_button.clicked.connect(lambda: self.a_class.an_object.do_something())
    self.ui.my_button.clicked.connect(lambda: self.a_class.an_object.do_something(sef))
    

    Thanks a lot if someone helps, im new to all this, if you make a simple example i will be thanking you forever



  • @adrian88888888

    @SGaist said in how to connect a def to a Qt button?, and where to put the def?:
    The first of all the options you provided.

    I am surprised at @SGaist's answer --- maybe in all his question-answering he is muddling his Python with his C++, or he has a counting issue. ;-) In Python it is the second of your options, but without the parentheses, which is required:

    self.ui.my_button.clicked.connect(self.do_something)
    

    Assuming do_something() is a method in the current class. Or, it might be someObject.do_something if you want to call a slot in another module. Plain do_something here would only be right if that were a global function.

    As for lambda: If the signal you are connecting and the slot you are connecting to have the same parameter signatures you do not need a lambda (straightforward case). If you want to do more advanced stuff, like pass an extra parameter, a lambda is a nice way to do it. And that case might then be:

    self.ui.my_button.clicked.connect(lambda: self.do_something(self.ui.my_button))
    

  • Lifetime Qt Champion

    Hi,

    It will depend. If your method is part of your class, then the first one but with the parenthesis removed after do_something.

    On a side note, do not call show in the constructor, that's bad practice. It's the role of the class/method handling this object to choose when it's appropriate to show the widget.



  • @SGaist what you mean by "then the first one", what first one?

    I get what you say about not calling the show in the constructor, but i don't understand what you mean by "It's the role of the class/method", what class? the MainWindow?, but its inside that one


  • Lifetime Qt Champion

    The first second of all the options you provided.

    MainWindow is not in charge of showing itself.

    In your case it's the main method where you create it where you should call show.

    [edit: off by one error SGaist]



  • @adrian88888888

    @SGaist said in how to connect a def to a Qt button?, and where to put the def?:
    The first of all the options you provided.

    I am surprised at @SGaist's answer --- maybe in all his question-answering he is muddling his Python with his C++, or he has a counting issue. ;-) In Python it is the second of your options, but without the parentheses, which is required:

    self.ui.my_button.clicked.connect(self.do_something)
    

    Assuming do_something() is a method in the current class. Or, it might be someObject.do_something if you want to call a slot in another module. Plain do_something here would only be right if that were a global function.

    As for lambda: If the signal you are connecting and the slot you are connecting to have the same parameter signatures you do not need a lambda (straightforward case). If you want to do more advanced stuff, like pass an extra parameter, a lambda is a nice way to do it. And that case might then be:

    self.ui.my_button.clicked.connect(lambda: self.do_something(self.ui.my_button))
    


  • @SGaist ah, and where i should put the do_something()? as a module inside that class? or as a module of other class in other .py file? because i saw that before

    what is a main method? you mean inside Ui_MainWindow()?



  • @JonB thanks a lot!, that explanation was what i needed



  • @adrian88888888
    Write the do_something() slot in the module where it is most appropriate for what it needs to do. In the simplest case that will be here, in MainWindow, and then the slot can access the other widgets & variables here.

    You should move the self.show() out of MainWindow and into creator/caller:

        window = MainWindow()
        window.show()
    

  • Lifetime Qt Champion

    @JonB indeed off by one error, good catch.



  • @JonB I see now, thanks again!


Log in to reply