当前位置: 首页 > 知识库问答 >
问题:

为什么有些小部件在Qt5上不更新?

赖翰
2023-03-14

我正在尝试创建一个PyQt5应用程序,其中我使用了某些标签来显示状态变量。为了更新它们,我手动实现了自定义pyqtSignal。然而,在调试时,我发现GUIQLabel的值发生了变化,但是这些值没有反映在主窗口上。

一些答案建议调用QApplication()。processEvents()偶尔。但是,这会立即使应用程序崩溃,并冻结应用程序。

这是一个示例代码(所有必需的库都被导入,这只是部分创建问题,实际代码很大):

from multiprocessing import Process

def sub(signal):
    i = 0
    while (True):
        if (i % 5 == 0):
            signal.update(i)

class CustomSignal(QObject):
    signal = pyqtSignal(int)
    def update(value):
        self.signal.emit(value)

class MainApp(QWidget):
    def __init__(self):
        super().__init__()
        self.label = QLabel("0");
        self.customSignal = CustomSignal()
        self.subp = Process(target=sub, args=(customSignal,))
        self.subp.start()
        self.customSignal.signal.connect(self.updateValue)

    def updateValue(self, value):
        print("old value", self.label.text())
        self.label.setText(str(value))
        print("new value", self.label.text())

print语句的输出与预期一致。但是,标签中的文本不会更改。

CustomSignal中的update函数由某个线程调用。我用同样的方法更新进度条,效果很好。

除了processEvents(),是否还有其他修复方法?

操作系统是Ubuntu 16.04。

共有2个答案

钮勇
2023-03-14

尝试添加

self.label.repaint()

在更新文本后立即执行以下操作:

self.label.setText(str(value))
self.label.repaint()
姚和顺
2023-03-14

关键问题在于代码背后的概念。

进程有自己的地址空间,并且不与其他进程共享数据,除非使用某些进程间通信算法。可能是使用了多线程模块而不是线程模块来实现并发,以避免Python的GIL并加速程序。但是,子进程无法访问父进程的数据。

我已经测试了两种解决方案,它们似乎有效。

>

  • 线程模块:尽管由于GIL,Python中的线程处理效率很低,但在某种程度上仍然足以满足基本的并发需求。请注意并发和加速之间的区别。

    QType:因为使用PYQT,所以使用Q线程没有任何问题,这是一个更好的选择,因为它利用了操作系统的系统调用,而不是Python中间的多个内核。

  •  类似资料:
    • 我面临的一些问题,没有收到通知在一些电话。我也不接受GCM的意图。这是我打电话给GCM注册时的日志。在像Nexus和Moto这样的手机上,它运行得非常好。但在Lava和Karbonn这样的低端手机上,我就面临着这个问题。 D/PowerManagerService(649):AcquireWakeLockInternal:lock=1114432392,Flags=0x1,tag=“gcm_con

    • 问题内容: 下面显示的是我班的简化版本。我在onReceive方法上遇到了麻烦,该方法没有更新小部件TextView。它在logcat中显示正确的信息,该信息在setTextViewText之前的行上输出。我不确定出什么问题了,并且一直在拔头发(而且我已经秃顶了)。 } 问题答案: 找到了答案。调用后,您需要通过调用来更新窗口小部件。我添加的代码如下所示。

    • 我试图在我的应用程序中集成不同大小的图像,但问题是在Android Studio中没有可绘制的-IDPI、mdpi、hdpi、xhdpi文件夹。我已经检查了其他线程,答案是我只需要跳到项目视图,而不是Android视图。但结果是一样的。只有一个名为drawable的通用文件夹 如果我尝试添加另一个资源文件夹,则drawable将丢失。

    • 所以我一直在尝试只在ios上添加一些填充,而不是在Android上。是否有任何方法可以检查我是否使用android或ios,以便在我的应用程序中实现此功能。提前谢谢。

    • 问题内容: 这样的事情会使小部件正常显示: 虽然这样,将使小部件完全不显示: 问题答案: 您可能对 小部件的和方法感兴趣。在以下示例中,单击后按钮消失

    • 在研究tkinter多线程时,我发现tkinter必须在主线程上运行(就像许多GUI框架),当一个单独的线程需要与GUI通信时,必须使用队列,而不是直接从工作线程访问小部件。 我试图学习使用队列方法,但当然最初我想看看如果我做错了会发生什么,所以我写了这段代码,它近似于Pi(π)几秒钟: 据我所知,由注释是问题。但是这个代码运行得很好。保持响应,标签和进度条都会更新。