How to move class method out of gui modul



  • Hello, this is my first post here. Very small and simple working example of GUI with radiobutton is posted to describe the situation. It contains two modules: "main.py" and "gui.py" (made by QTCreator). Module "gui.py" contains methos "print_situation", which is called from main module. I would like to moove this method into third module called "apps.py" in to class "my_app" and I would still like to call it from main module, from the same place.
    I don't know if this is even possible, becouse searching over net didn't find any example like this one.
    So, the question is: how to do it? This solution would simplify my large project.

    Regards, Vlado

    main.py

    # python 2.7.9
    
    from PyQt4 import QtCore, QtGui
    from gui import Ui_Form
    import sys
    
    
    if __name__ == "__main__":
    
        app = QtGui.QApplication(sys.argv)
    
        gui_master = QtGui.QWidget()
        master = Ui_Form()
        master.setupUi(gui_master)
    
        master.radioButton.clicked.connect(master.print_situation)
    
        gui_master.show()
        sys.exit(app.exec_())
    

    gui.py

    from PyQt4 import QtCore, QtGui
    
    try:
        _fromUtf8 = QtCore.QString.fromUtf8
    except AttributeError:
        def _fromUtf8(s):
            return s
    
    try:
        _encoding = QtGui.QApplication.UnicodeUTF8
        def _translate(context, text, disambig):
            return QtGui.QApplication.translate(context, text, disambig, _encoding)
    except AttributeError:
        def _translate(context, text, disambig):
            return QtGui.QApplication.translate(context, text, disambig)
    
    class Ui_Form(object):
        def setupUi(self, Form):
            Form.setObjectName(_fromUtf8("Form"))
            Form.resize(300, 150)
            self.radioButton = QtGui.QRadioButton(Form)
            self.radioButton.setGeometry(QtCore.QRect(100, 75, 118, 26))
            self.radioButton.setObjectName(_fromUtf8("radioButton"))
    
            self.retranslateUi(Form)
            QtCore.QMetaObject.connectSlotsByName(Form)
    
        def retranslateUi(self, Form):
            Form.setWindowTitle(_translate("Form", "Form", None))
            self.radioButton.setText(_translate("Form", "RadioButton", None))
    
        def print_situation(self):
            if self.radioButton.isChecked():
                print "Checked"
            else:
                print "Unchecked"
    
    
    if __name__ == "__main__":
        import sys
        app = QtGui.QApplication(sys.argv)
        Form = QtGui.QWidget()
        ui = Ui_Form()
        ui.setupUi(Form)
        Form.show()
        sys.exit(app.exec_())
    
    
    

  • Lifetime Qt Champion

    HI and welcome to devnet,

    You can't move a class method out of a class in python.

    What exactly are you trying to accomplish ?



  • Hi and thanks for your reply. In my project code "gui.py" module takes already more than 800 lines of code and and it's not even finished. I would like to keep this module as small as possible. But if you say mooving methods like "print_situation" out of the class "Ui_Form" is impossible then there is nothing I can do.
    My project involves Raspberry Pi as a Masteri in RS485 network with several slaves for meassuring temperatures, air preassure, consumption of electric energy, ...
    Everything Works ok so far, but it's not finished yet. I Will post some pictures later this day
    I intend to add some diagrams into project, what tool or librarry would you suggest to do that?

    Regards, Vlado


  • Moderators

    @California Depending on what this print_situation does you can move its content to a function/method in apps.py and call it from print_situation


  • Qt Champions 2016

    Hi
    Disclaimer: Python noob :)

    Since Python do not seem to have any concept of Private, there should be nothing wrong with
    some function are in other file or object. You just have to give parameter so it can access what it needs

    def print_situation(self):
    if self.radioButton.isChecked():
    print "Checked"
    else:
    print "Unchecked"

    So I assume if you call it from main
    otherclass.print_situation(gui_master)

    and it would still work. as the Self then would have radioButton.
    Or might need you define the object/function like
    class OtherClass(object):
    def myPrint(self, Form):

    To allow myPrint to talk to Forms widgets.

    This have one big disadvantages though. You will bleed details to the other modules in terms it knows what controls the form has etc.

    For a better design, you can use signals
    Just define some new Signals in the main Form for the data that needs to flow there.
    The classes in apps.py" then just have the slots and you hook it all up
    in main.

    So in main you would just
    emit Print( data_for_print )

    and some class in apps would do the real work.



  • @jsulm name of the method "print_situation" is just for testing. Real method looks like this one below.

        def read_190_allowed(self):
            if self.radioButton.isChecked():
                read_flag == 1
            else:
                read_flag == 0
            return read_flag
    

    @mrjj forgive me, I am fighting with python for last six months, so my knowledge is very limitted so far ...
    I did not use signals yet, but this is the chance to do it.
    Some test code with third module including error message will be posted here later.

    Ragards Vlado


  • Moderators

    @California I don't see what's the point to move these 5 lines of code to another location.


  • Lifetime Qt Champion

    Depending on how "the file is getting too big", you may have an architecture problem. Proper encapsulation is as important in python than it is in C++.



  • @jsulm If there would only this method it wouldn't be a problem at all, but with a lot of them ...
    Complete module will be posted here, maybe there is another way to do the same thing ...



  • Ok, module "gui.py" is posted below. Also imidge of the front page of my GUI.
    I had to delete code made by QTCreator (to much characters ...)

    # -*- coding: utf-8 -*-
    
    # Form implementation generated from reading ui file 'Master_26b.ui'
    #
    # Created: Mon Jan  9 16:23:54 2017
    #      by: PyQt4 UI code generator 4.11.2
    #
    # WARNING! All changes made in this file will be lost!
    
    from PyQt4 import QtCore, QtGui
    import PyQt4.Qwt5 as Qwt
    from slave_160 import(convert_byte_to_bin_out, convert_long_to_bytes,
        convert_float_to_MICROCHIP_32bit, convert_MICROCHIP_32bit_to_float,
        crc_calc, set_temp, read_temp)
    from slave_190a import(read_time, set_time, check_heating, control_heating,
        control_heating_5_6, set_time_zg, set_time_sp)
    from slave_220 import(convert_MICROCHIP_32bit_to_float, crc_calc,
         read_hladilnica, convert_byte_to_bin_out_2, set_hladilnica,
          convert_float_to_MICROCHIP_32bit, convert_long_to_bytes)
    from PyQt4.QtCore import *
    from PyQt4.QtGui import *
    
    try:
        _fromUtf8 = QtCore.QString.fromUtf8
    except AttributeError:
        def _fromUtf8(s):
            return s
    
    try:
        _encoding = QtGui.QApplication.UnicodeUTF8
        def _translate(context, text, disambig):
            return QtGui.QApplication.translate(context, text, disambig, _encoding)
    except AttributeError:
        def _translate(context, text, disambig):
            return QtGui.QApplication.translate(context, text, disambig)
    
    
    class Ui_Izbira(QtGui.QWidget):  # class Ui_Izbira(object):  DELA ENAKO V OBEH PRIMERIH
        def setupUi(self, Izbira):
            Izbira.setObjectName(_fromUtf8("Izbira"))
            Izbira.resize(908, 619)
    
            Izbira.setStyleSheet(_fromUtf8("background-color: rgb(200, 200, 200);"))
            self.col = QtGui.QColor(0, 0, 0)
    
        ...
    
        def set_time_zgoraj(self, arg):
            time_zg = int(self.lineEdit_Up_day.text())
            set_time_zg(time_zg)
    
        def set_time_spodaj(self, arg):
            time_sp = (int(self.lineEdit_Down_day.text()) + 10)
            set_time_sp(time_sp)
    
        def vklop_izklop_ogrevanje(self):
            if self.Ogrevanje_izven_sezone.checkState() == QtCore.Qt.Checked:
                komanda = 241
            else:
                komanda = 31
    
            ogrevanje = control_heating(komanda)
    
            if ogrevanje == 74:
                val = 255
            else:
                val = 0
    
            self.col.setGreen(val)
            self.Ogrevanje_sezona_aktivno.setStyleSheet(
                "QFrame { background-color: %s }" %
                self.col.name())
    
        def read_190_allowed(self):
            if self.checkBox_Read_190.checkState() == QtCore.Qt.Checked:
                read_190_flag = 1
            else:
                read_190_flag = 0
            return read_190_flag
    
        def up_5_6_OnOff(self):
            if self.checkBox_Up_5_6.checkState() == QtCore.Qt.Checked:
                up_5_6 = 27
            else:
                up_5_6 = 26
            ogrevanje_5_6 = control_heating_5_6(up_5_6)
    
            if ogrevanje_5_6 == 27:
                val = 255
            else:
                val = 0
    
            self.col.setGreen(val)
            self.Ogrevanje_zgoraj_5_6.setStyleSheet(
                "QFrame { background-color: %s }" %
                self.col.name())
    
        def set_time_190(self, arg, ):
            num_year = int(self.lineEdit_Year.text())
            num_month = int(self.lineEdit_Month.text())
            num_day = int(self.lineEdit_Day.text())
            num_hour = int(self.lineEdit_Hour.text())
            num_min = int(self.lineEdit_Minutte.text())
            num_sec = int(self.lineEdit_Seconds.text())
            num_wekday = int(self.lineEdit_WeekDay_SET.text())
            num_up56 = 26
            num_up = int(self.lineEdit_Up_day.text())
            num_down = int(self.lineEdit_Down_day.text()) + 10
            set_time(num_year, num_month, num_day, num_hour,
                num_min, num_sec, num_wekday, num_up56, num_up, num_down)
    
        def read_slave_190(self):
            timecomplete = read_time()
            self.lineEdit_Year.setText(str("%.0f" % timecomplete[0]))
            self.lineEdit_Month.setText(str("%.0f" % timecomplete[1]))
            self.lineEdit_Day.setText(str("%.0f" % timecomplete[2]))
            self.lineEdit_Hour.setText(str("%.0f" % timecomplete[3]))
            self.lineEdit_Minutte.setText(str("%.0f" % timecomplete[4]))
            self.lineEdit_Seconds.setText(str("%.0f" % timecomplete[5]))
            self.lineEdit_WeekDay_SET.setText(str("%.0f" % timecomplete[6]))
    
            if timecomplete[6] == 1:
                self.lineEdit_WeekDay.setText("Ponedeljek")
            elif timecomplete[6] == 2:
                self.lineEdit_WeekDay.setText("Torek")
            elif timecomplete[6] == 3:
                self.lineEdit_WeekDay.setText("Sreda")
            elif timecomplete[6] == 4:
                self.lineEdit_WeekDay.setText("Cetrtek")
            elif timecomplete[6] == 5:
                self.lineEdit_WeekDay.setText("Petek")
            elif timecomplete[6] == 6:
                self.lineEdit_WeekDay.setText("Sobota")
            elif timecomplete[6] == 7:
                self.lineEdit_WeekDay.setText("Nedelja")
            self.lineEdit_Up_day.setText(str("%.0f" % timecomplete[8]))
            self.lineEdit_Down_day.setText(str("%.0f" % (timecomplete[9] - 10)))
            ogrevanje = check_heating()
            if ogrevanje == 74:
                val = 255
            else:
                val = 0
            self.col.setGreen(val)
            self.Ogrevanje_sezona_aktivno.setStyleSheet(
                "QFrame { background-color: %s }" %
                self.col.name())
    
        def read_slave_220(self):
            hladilnica = read_hladilnica()
            self.lineEdit_Hladilnica_Temperatura.setText(str("%.2f" % hladilnica[0]))
            self.lineEdit_Hladilnica_Vlaga.setText(str("%.2f" % hladilnica[1]))
            self.lineEdit_Hladilnica_set_temp.setText(str("%.0f" % hladilnica[2]))
            #self.lineEdit_Hladilnica_set_temp.setText(str("%.1f" % (float(hladilnica[2] / 10))))
            self.lineEdit_Hladilnica_set_vlaga.setText(str("%.0f" % hladilnica[3]))
            a = convert_byte_to_bin_out_2(hladilnica[4])
            if a[0] == 1:
                val = 255
            else:
                val = 0
            self.col.setGreen(val)
            self.Hladilnica_kompresor_aktivno.setStyleSheet("QFrame { background-color: %s }" %
                self.col.name())
            if a[1] == 1:
                val = 255
            else:
                val = 0
            self.col.setGreen(val)
            self.Hladilnic_vlazilec_aktivno.setStyleSheet("QFrame { background-color: %s }" %
                self.col.name())
            if a[1] == 1:
                val = 255
            else:
                val = 0
            self.col.setGreen(val)
            self.Hladilnica_ventilator_aktivno.setStyleSheet("QFrame { background-color: %s }" %
                self.col.name())
    
        def set_slave_220(self, arg):
            num_ht = int(self.lineEdit_Hladilnica_set_temp.text())
            #num_ht = int(float(self.lineEdit_Hladilnica_set_temp.text()))
            num_hv = int(self.lineEdit_Hladilnica_set_vlaga.text())
            set_hladilnica(7.5, 75, num_ht, num_hv, 0)
    
        def set_slave_160(self, arg):
            num_zg = float(self.lineEdit_SZgoraj.text())
            num_sp = float(self.lineEdit_SSpodaj.text())
            set_temp(num_zg, num_sp)
    
        def read_slave_160(self):
            temp = read_temp()
            self.lineEdit_ZG.setText(str("%.2f" % temp[0]))
            self.lineEdit_SP.setText(str("%.2f" % temp[1]))
            self.lineEdit_BO.setText(str("%.2f" % temp[2]))
            self.lineEdit_SO.setText(str("%.2f" % temp[3]))
            self.lineEdit_PE.setText(str("%.2f" % temp[4]))
            self.lineEdit_ZU.setText(str("%.2f" % temp[5]))
            self.lineEdit_SZgoraj.setText(str("%.2f" % temp[6]))
            self.lineEdit_SSpodaj.setText(str("%.2f" % temp[7]))
            a = convert_byte_to_bin_out(temp[8])
    
            if a[0] == 1:
                val = 255
            else:
                val = 0
    
            self.col.setGreen(val)
            self.Pec_aktivno.setStyleSheet("QFrame { background-color: %s }" %
                self.col.name())
    
            if a[1] == 1:
                val = 255
            else:
                val = 0
    
            self.col.setGreen(val)
            self.Sonce_aktivno.setStyleSheet("QFrame { background-color: %s }" %
                self.col.name())
    
            if a[2] == 1:
                val = 255
            else:
                val = 0
    
            self.col.setGreen(val)
            self.Bojler_aktivno.setStyleSheet("QFrame { background-color: %s }" %
                self.col.name())
    
            if a[3] == 1:
                val = 255
            else:
                val = 0
    
            self.col.setGreen(val)
            self.Spodaj_aktivno.setStyleSheet("QFrame { background-color: %s }" %
                self.col.name())
    
            if a[4] == 1:
                val = 255
            else:
                val = 0
    
            self.col.setGreen(val)
            self.Zgoraj_aktivno.setStyleSheet("QFrame { background-color: %s }" %
                self.col.name())
    
            if a[5] == 1:
                val = 255
            else:
                val = 0
    
            self.col.setGreen(val)
            self.Crpalka_aktivno.setStyleSheet("QFrame { background-color: %s }" %
                self.col.name())
    
    #from qwt_plot import QwtPlot
    
    if __name__ == "__main__":
        import sys
        app = QtGui.QApplication(sys.argv)
        Izbira = QtGui.QTabWidget()
        ui = Ui_Izbira()
        ui.setupUi(Izbira)
        Izbira.show()
        sys.exit(app.exec_())
    
    
    

    slave 190



  • Picture of GUI is missing ...

    alt text



  • Ok, this time succesed.
    alt text
    alt text
    alt text


  • Lifetime Qt Champion

    Just a quick note, you do realise that you are modifying a file which clearly states in its header that it can be regenerated and all your modification lost ?



  • Back with 3 modules. Take a look please

    main_1

    # python 2.7.9
    
    from PyQt4 import QtCore, QtGui
    from gui_1 import Ui_Form
    from apps_1 import my_app
    import sys
    
    
    if __name__ == "__main__":
    
        app = QtGui.QApplication(sys.argv)
    
        #a = my_app.print_situation(Ui_Form)
    
        gui_master = QtGui.QWidget()
        master = Ui_Form()
        master.setupUi(gui_master)
    
        master.radioButton.clicked.connect(my_app.print_situation)
    
        gui_master.show()
        sys.exit(app.exec_())
    
    

    gui_1

    # -*- coding: utf-8 -*-
    
    # Form implementation generated from reading ui file 'gui_2.ui'
    #
    # Created: Tue Jan 31 18:01:54 2017
    #      by: PyQt4 UI code generator 4.11.2
    #
    # WARNING! All changes made in this file will be lost!
    
    from PyQt4 import QtCore, QtGui
    
    try:
        _fromUtf8 = QtCore.QString.fromUtf8
    except AttributeError:
        def _fromUtf8(s):
            return s
    
    try:
        _encoding = QtGui.QApplication.UnicodeUTF8
        def _translate(context, text, disambig):
            return QtGui.QApplication.translate(context, text, disambig, _encoding)
    except AttributeError:
        def _translate(context, text, disambig):
            return QtGui.QApplication.translate(context, text, disambig)
    
    class Ui_Form(object):
        def setupUi(self, Form):
            Form.setObjectName(_fromUtf8("Form"))
            Form.resize(300, 150)
            self.radioButton = QtGui.QRadioButton(Form)
            self.radioButton.setGeometry(QtCore.QRect(100, 75, 118, 26))
            self.radioButton.setObjectName(_fromUtf8("radioButton"))
    
            self.retranslateUi(Form)
            QtCore.QMetaObject.connectSlotsByName(Form)
    
        def retranslateUi(self, Form):
            Form.setWindowTitle(_translate("Form", "Form", None))
            self.radioButton.setText(_translate("Form", "RadioButton", None))
    
    #    def print_situation(self):
    #        if self.radioButton.isChecked():
    #            print "Checked"
    #        else:
    #            print "Unchecked"
    
    
    if __name__ == "__main__":
        import sys
        app = QtGui.QApplication(sys.argv)
        Form = QtGui.QWidget()
        ui = Ui_Form()
        ui.setupUi(Form)
        Form.show()
        sys.exit(app.exec_())
    

    apps_1

    # python 2.7.9
    from PyQt4 import QtCore, QtGui
    from gui_1 import Ui_Form
    
    
    class my_app(QtGui.QRadioButton, Ui_Form):
        def __init__(self, parent=None):
            super(my_app, self).__init__(parent)
            self.setupUi(self)
            self.radioButton = QtGui.QRadioButton()
    
        def print_situation(self):
            if self.radioButton.isChecked():
                print "Checked"
            else:
                print "Unchecked"
    

    error message

    Traceback (most recent call last):
      
    File "/home/pi/Desktop/Qt4/Project/01/Test_Class_2/main_1.py", line 19, in <module>
        
    master.radioButton.clicked.connect(my_app.print_situation)
    
    AttributeError: 
    'function' object has no attribute '__pyqtSignature__'
    

  • Moderators

    @California You should not move anything out of gui.py as it is auto-generated (as @SGaist already said). You should never touch auto-generated stuff.



  • @jsulm copy that. What is max size of the module to work properly?


  • Moderators

    @California There is no such max size. But for your own modules you should try to keep them small (not more than some hundreds of lines if possible), else it will be hard to understand them or change something. How big auto-genereated modules are doesn't matter as you should not change anything there and usually you do not want to read this code.



  • @jsulm In my case gui.py is quite big because all methods related to GUI must be inside GUI class. The problem is, project is not finished yet, so this module will be even bigger after some time.
    About diagrams, what tool or library should be used in my project?


  • Moderators

    @California Is it really that important how big this auto-generated gui.py is?
    Diagrams? See QtCharts.



  • @jsulm When QTCreator is used, your code is big as my very fast. Tab controll with few pages produce plenty of lines of code ...
    Ok, few words about my project.
    My project involves RaspberryPi as a Master in RS485 network. This application is like a sort of SCADA for home. On the other side of the network there are slaves responsible for diferent things like temperatures, humidity, consumption of watter, electricity, ...
    So Master collets those data, do some calcullations, diagrams, storing data, ... , and most important do some graphic visualisation of everything in network.
    At the momment my code covers three slaves, but there are three slaves more to include into aplication. Each slave contains Microchip microcontroller PIC18F458 ...
    Slaves are already in function in real situation.


  • Moderators

    @California To keep your gui.py smaller you can create one widget for each tab in its own file (using designer, widget_1.py, widget_2.py, ...). Then add those widgets to the tabs.



  • @jsulm that would be very usefull, do you have any example of how to do it or where it could be find to look?


  • Lifetime Qt Champion

    What are your skills level with python ?



  • @SGaist I started to learn python six months ago with my project described above


  • Lifetime Qt Champion

    So you know how to split your code in several logical modules/files and import them to use them ?



  • @SGaist No probles with importing functions, more troubles with classes, specially with everything related to gui.
    My project is unique and it's not comercial.



  • Smal change in function makes script running without an error but only "Unchecked" is printed out when radiobutton is checked or it is unchecked. How to fix this to have correct respond?

    # python 2.7.9
    from PyQt4 import QtCore, QtGui
    #from gui_1 import Ui_Form
    
    
    def print_situation(*args):
        radioButton = QtGui.QRadioButton()
        if radioButton.isChecked():
            print "Checked"
        else:
            print "Unchecked"
    

  • Lifetime Qt Champion

    Importing functions or classes is exactly the same process.

    The thing that you seem to want to do is take apart class functions

    Take a look at the 3rd example from the PyQt 5 designer introduction documentation.

    Basically, you have your generated file from pyuic5, then you create your own class that will use the generated code. Finally a main.py where you will instantiate your custom widget(s) and start the application.


  • Qt Champions 2016

    Hi
    Wont

    def print_situation(*args):
        radioButton = QtGui.QRadioButton()
        if radioButton.isChecked():
            print "Checked"
        else:
            print "Unchecked"
    

    radioButton = QtGui.QRadioButton()
    create a new QRadioButton

    Each time and its unchecked by default.

    Hence it always says "Unchecked" ?



  • @mrjj you are right I suppose

    @SGaist I tried to follow your point but ...
    code:

    # python 2.7.9
    from PyQt4 import QtCore, QtGui
    from PyQt4.QtGui import QCheckBox
    #from gui_5 import Ui_Form
    
    
    class My_app(QCheckBox):
        def __init__(self):
            super(My_app, self).__init__()
            # Set up the user interface from Designer.
            self.setupUi(self)
            self.checkBox = QtGui.QCheckBox(self)
            # Connect up the buttons.
            self.checkBox.clicked.connect(self.accept)
    
        def print_situation(self, *args):
            if self.checkBox.checkState() == QtCore.Qt.Checked:
                print "Checked"
            else:
                print "Unchecked"
    

    error:

    Traceback (most recent call last):
      File "/home/pi/Desktop/Qt4/Project/01/Test_Class/main_5.py", line 17, in <module>
        master.checkBox.clicked.connect(My_app.print_situation)
    AttributeError: 'function' object has no attribute '__pyqtSignature__'
    

  • Lifetime Qt Champion

    Why are you deriving from a QCheckBox and then create a new checkbox in it ?



  • Would you be so kind to rewritte this code to loose error, because I am lost at the momment.
    A lot of time was spent for this issue in last month and I didn't make any progress at all.



  • I will take no respond as this issue is mission impossible.
    Thanks for your help.

    Vlado


  • Qt Champions 2016

    @California said in How to move class method out of gui modul:

    mission impossible.

    Well you seem to lack (some ?) understanding of classes in python.
    https://www.tutorialspoint.com/python/python_classes_objects.htm

    I think all the issue comes from that. Using Qt does not change anything.

    So maybe stop with Qt for a day. Try to use own objects like you want to with Qt.

    If you do not know how to make instance of a class or how to use them as parameters etc then
    its hard to split to extra files.

    Just saying. Im even bigger Beginner with python. :)



  • Thanks for this useffull link.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.