简体   繁体   English

Python 3 pyQt4使用来自多个模块/类的变量更新GUI

[英]Python 3 pyQt4 updating GUI with variables from multiple modules/classes

I've written a large program with nested classes/threads and multiple modules. 我编写了一个带有嵌套类/线程和多个模块的大型程序。 I would now like to add a simple GUI and some Labels to display some variables. 我现在想添加一个简单的GUI和一些标签来显示一些变量。 However, the variables are scattered throughout the modules and classes. 但是,变量分散在整个模块和类中。 I'm looking for a way to update these variables into the GUI without altering the current code too much. 我正在寻找一种方法来将这些变量更新到GUI中,而不会过多地更改当前代码。

I have a rudimentary understanding of Pyqt4 (i will accept tkinter answers also). 我对Pyqt4有基本的了解(我也会接受tkinter的答案)。

I've tried not to use signals/emits because to my knowledge emits must be sent from a Qthread which would mean a complete overhaul of my code, changing classes and threads over to Qthreads. 我尝试不使用信号/发出信号,因为据我所知,发出的信号必须从Qthread发送,这意味着对我的代码进行彻底的检查,将类和线程更改为Qthreads。 Id like to avoid needing to do this if possible. 如果可能的话,我想避免这样做。 Here is one example I've attempted. 这是我尝试过的一个例子。

test.py test.py

class Update(Thread): 
    def __init__(self): 
        Thread.__init__(self) 
    def run(self): 

        for i in range(10): 
            time.sleep(2) 
            import test 
            wa.label.setText(str(i)) 

class MyWindow(QWidget):  
    def __init__(self, *args):  
        QWidget.__init__(self, *args) 

        self.label = QLabel(" ") 
        layout = QVBoxLayout() 
        layout.addWidget(self.label) 
        self.setLayout(layout) 

        Update1 = Update() 
        Update1.start() 
        Update1.refresh1 = 'ba' 

        self.label.setText(Update1.refresh1) 


if __name__ == "__main__":  
    app = QApplication(sys.argv)  
    wa = MyWindow()  
    wa.show()  
    sys.exit(app.exec_()) 

This code works, but my variables need to update from other modules/classes or threads. 该代码有效,但是我的变量需要从其他模块/类或线程更新。 The moment I move 'class Update' into a new module like THIS: 当我将“类更新”移至新模块(如THIS)的那一刻:

test.py test.py

import test2 


class MyWindow(QWidget):  
    def __init__(self, *args):  
        QWidget.__init__(self, *args) 

        self.label = QLabel(" ") 
        layout = QVBoxLayout() 
        layout.addWidget(self.label) 
        self.setLayout(layout) 

        Update1 = test2.Update() 
        Update1.start() 
        Update1.refresh1 = 'ba' 

        self.label.setText(Update1.refresh1) 


if __name__ == "__main__":  
    app = QApplication(sys.argv)  
    wa = MyWindow()  
    wa.show()  
    sys.exit(app.exec_()) 

test2.py #updates GUI test2.py #更新GUI

class Update(Thread): 
    def __init__(self): 
        Thread.__init__(self) 
    def run(self): 

        for i in range(10): 
            time.sleep(2) 
            import test 
            test.wa.label.setText(str(i)) 

I get: AttributeError: 'module' object has no attribute 'wa' 我得到: AttributeError: 'module' object has no attribute 'wa'

Also, I was also considering putting class Update() into a Qthread, running it from any module/class where a variable has been updated and using the emit function inside Update(). 另外,我还考虑将类Update()放入Qthread中,从已更新变量的任何模块/类中运行它,并在Update()中使用发出函数。 this would solve having to change my current classes/threads to be Qthreads. 这将解决必须将我当前的类/线程更改为Qthreads的问题。

If anyone knows of a simple way I could update my GUI simply by calling a class like update() an example would be appreciated 如果有人知道一种简单的方法,我可以通过调用诸如update()之类的类来更新我的GUI,将不胜感激

Because wa is only set when __name__ == "__main__" and that only happens when test.py is the main file. 因为wa仅在__name__ == "__main__"时设置,并且仅在test.py是主文件时才设置。

When you do import test , you are running another instance of the test.py file which is not the main script so it has __name__ == 'test' not __main__ . import test ,您正在运行test.py文件的另一个实例,该实例不是主脚本,因此它具有__name__ == 'test'而不是__main__ So, even if wa was set, you would be changing another instance of it. 因此,即使设置了wa ,您也将更改它的另一个实例。

Possible solution: 可能的解决方案:

You can get a reference to the __main__ module and set on the test2.py module: 您可以获取对__main__模块的引用,并在test2.py模块上进行设置:

On test.py : test.py上

import test2
test2.parent = sys.modules[__name__]

Now, on test2.py (do not import test but make sure test imports test2 ): 现在,在test2.py上 (不导入test但确保test导入test2 ):

parent.wa.label.setText('Blablabla')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM