Updating a Qt object when reloading a module that defines a class subclassing this Qt object

橙三吉。 提交于 2019-12-11 02:39:29

问题


How to have all attributes and Qt views of an object updated when reloading the python module that defines this object, without breaking or even touching the links between this object and other objects?

Here is an exemple: The QMainWindow of a Qt application includes both local widgets and a reloadable widget:

from PyQt4 import QtCore, QtGui
import reloadable

name='Test reloadable'

class MyWindow(QtGui.QMainWindow):

    def __init__(self):
        # Initialize the main window
        super(MyWindow, self).__init__()
        self.setWindowTitle(name)
        # Create an instance of the reloadable widget
        self.reloadableWidget= reloadable.ReloadabelWidget()    
        # Create a local widget that can ask for and display an attribute of the reloadable widget  
        button1 = QtGui.QPushButton('Identify')
        button1.clicked.connect(self.identifyReloadable)
        self.label1=QtGui.QLabel('')
        layout1 = QtGui.QHBoxLayout()
        layout1.addWidget(button1)
        layout1.addWidget(self.label1)
        localWidget=QtGui.QWidget()
        localWidget.setLayout(layout1)
        # Put the local widget and the reloadable widget in the window
        centralWidget=QtGui.QWidget()
        layout = QtGui.QVBoxLayout()
        layout.addWidget(localWidget)
        layout.addWidget(self.reloadableWidget)
        centralWidget.setLayout(layout)
        self.setCentralWidget(centralWidget)    

    def identifyReloadable(self):
        identity=self.reloadableWidget.identify()
        self.label1.setText(identity)

if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    app.setApplicationName(name)
    main = MyWindow()
    main.show()
    sys.exit(app.exec_())

This reloadable widget (QFrame) has a method 'identify()' called by main and a method 'reload()' called by itself. This reload method essentially reloads the class module, replace the class attribute by the possibly updated module.class, and tries to update the Qt views of the object.

# This is module reloadble.py
from PyQt4 import QtCore, QtGui
import inspect
identity='1'
color='blue'

class ReloadabelWidget(QtGui.QFrame,object):

    def __init__(self):
        QtGui.QFrame.__init__(self)
        self.setFrameStyle(1)
        self.reinit()

    def reinit(self):
        button = QtGui.QPushButton('Reload',self)
        button.clicked.connect(self.reload) 
        label=QtGui.QLabel(identity)
        label.setStyleSheet("QLabel { background-color : white; color : %s; }" % color);
        layout = QtGui.QHBoxLayout()
        layout.addWidget(button)
        layout.addWidget(label)
        self.setLayout(layout)
        self.setUpdatesEnabled(True)

    def identify(self):
        return identity # will change each time the file is edited with a new identity in line 3

    def reload(self):
        module=inspect.getmodule(self)
        reload(module)
        self.reinit()   # object is reinitialized
        self.__class__= module.ReloadabelWidget # callable attributes are now up to date
        self.update()   # naive attempt to update the Qt view => does not work 
        # add code here to have the GUI part of self, i.e. the QFrame updated ...
        # ... whereever it is displayed.

The main application is running and the programmer redefines the method identify() and the color of a label by editing and saving the code of the reloadable module.

identity='2'
color='red'

The reload button is then clicked to run the reload() method of the reloadable widget. Its methods are properly updated and clicking the identify button displays the updated identity 2. But the widget's view is not updated because I don't know how to do it. What are the lines to be added at the end of the reload method to obtain the redisplay of the new interface, created by self.reinit() ?

PS1: For those who like to know what is the goal behind a question, I want to accelerate the development of a complicated multi-module application by having both the attributes and the gui of a module updated at code edition, without restarting the application.

PS2: This question replaces a bad one that I had asked without being sufficiently explicit. Since there was already several answers, I make this new post. I now provide a complete code entirely tested and make my point clearly.

来源:https://stackoverflow.com/questions/31492004/updating-a-qt-object-when-reloading-a-module-that-defines-a-class-subclassing-th

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!