PySide/PyQt:在 GUI 加载后执行函数 [英] PySide/PyQt: Execute functions after GUI loads

查看:77
本文介绍了PySide/PyQt:在 GUI 加载后执行函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个在会话启动时执行文件操作的小工具.为了确保用户有视觉反馈,我想将其与进度条相关联.

I am building a tiny tool that does file operations at session startup. In order to make sure the user has a visual feedback, I want to associate it with a progress bar.

到此为止:

import sys
import time
from PySide.QtGui import *


class ProgressWindowWidget(QWidget):
    def __init__(self, parent=None):
        super(ProgressWindowWidget, self).__init__()

        self.init_ui()

    def init_ui(self):
        self.setGeometry(500, 500, 600, 100)
        self.setWindowTitle('Progress')

        self.layout_ = QGridLayout()
        self.setLayout(self.layout_)

        self.progress_bar = QProgressBar()
        self.layout_.addWidget(self.progress_bar, 0, 0, 1, 1)

    def my_operations(self):
        print('do something 1')
        time.sleep(2)
        print('do something 2')
        time.sleep(2)
        print('do something 3')
        time.sleep(2)


def main():
    app = QApplication(sys.argv)
    progress_window = ProgressWindowWidget()
    progress_window.show()
    progress_window.my_operations()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

我的问题是 my_operations 首先执行,然后我的 GUI 被加载.我只想在加载进度条时执行 my_operations,以便我可以更新它.

My problem is that my_operations is executed first and then my GUI is loaded. I'd like to execute my_operations only when the progress bar is loaded, so I can update it.

根据this,它与exec_ main 循环,但这里显然有一些我不明白的地方,因为我在 show 之后调用了 my_operations.

According to this, it has something to do with the exec_ main loop, but there's obviously something I don't understand here because I am calling my_operations after show.

不用说,我是初学者.有没有人有想法?干杯

Needless to say, I'm a beginner. Does anyone have an idea? Cheers

推荐答案

每个 GUI 都存在于一个事件循环中,它允许您处理用户、操作系统等的事件,例如鼠标、键盘等,因此,如果您阻止此处理,GUI 将不会更新其状态,在您的情况下,问题是由 time.sleep() 引起的,它正在阻止,阻止 GUI 激活显示窗口的状态.所以作为一个基本规则:不要在 GUI 的主线程中使用 time.sleep(),我想 time.sleep() 模拟一个需要某些时候,对于这种情况,您必须从另一个线程执行此任务,如果要更新 GUI,则必须通过信号来完成,不应直接完成.

Every GUI lives in an event loop that allows you to handle events of the user, the OS, etc. such as the mouse, the keyboard, etc., so if you block this processing the GUI will not update its status, in your case the problem is caused by time.sleep(), which is blocking, preventing the GUI from activating the state of displaying the window. So as a basic rule: do not use time.sleep() inside the main thread of a GUI, I suppose the time.sleep() emulates a task that takes a certain time, for that case you must execute this task from another thread and if you want update the GUI you must do it by means of signals, it should not be done directly.

在下面的例子中,我将使用 threading.Thread() 创建一个新线程和一个信号来更新 GUI:

In the following example I will use threading.Thread() to create a new thread and a signal to update the GUI:

import sys
import time
import threading
from PySide import QtCore, QtGui


class ProgressWindowWidget(QtGui.QWidget):
    progressSignal = QtCore.Signal(int)

    def __init__(self, parent=None):
        super(ProgressWindowWidget, self).__init__()
        self.init_ui()

    def init_ui(self):
        self.setGeometry(500, 500, 600, 100)
        self.setWindowTitle('Progress')

        self.layout_ = QtGui.QGridLayout()
        self.setLayout(self.layout_)

        self.progress_bar = QtGui.QProgressBar()
        self.progressSignal.connect(self.progress_bar.setValue)
        self.layout_.addWidget(self.progress_bar, 0, 0, 1, 1)

    def my_operations(self):
        print('do something 1')
        time.sleep(2)
        self.progressSignal.emit(33)
        print('do something 2')
        time.sleep(2)
        self.progressSignal.emit(66)
        print('do something 3')
        time.sleep(2)
        self.progressSignal.emit(100)


def main():
    app = QtGui.QApplication(sys.argv)
    progress_window = ProgressWindowWidget()
    progress_window.show()
    t = threading.Thread(target=progress_window.my_operations)
    t.start()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

这篇关于PySide/PyQt:在 GUI 加载后执行函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆