PySide/PyQt: GUI加载后执行函数
PySide/PyQt: Execute functions after GUI loads
我正在构建一个在会话启动时执行文件操作的微型工具。为了确保用户有视觉反馈,我想将其与进度条相关联。
到目前为止我在这里:
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
,所以我可以更新它。
根据this,它与exec_ main
循环有关,但显然这里有一些我不明白的地方,因为我在[=16]之后调用my_operations
=].
不用说,我是初学者。有人有想法吗?
干杯
每个 GUI 都存在于一个事件循环中,允许您处理用户事件、OS 等事件,例如鼠标、键盘等,因此如果您阻止此处理 GUI不会更新它的状态,在你的情况下,问题是由 time.sleep()
引起的,它正在阻塞,阻止 GUI 激活显示 window 的状态。所以作为一个基本规则:不要在 GUI 的主线程中使用 time.sleep()
,我想 time.sleep()
模拟一个需要一定时间的任务,在这种情况下你必须从另一个线程执行这个任务如果你想更新 GUI,你必须通过信号来完成,它不应该直接完成。
在下面的示例中,我将使用 threading.Thread()
创建一个新线程和一个更新 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()
我正在构建一个在会话启动时执行文件操作的微型工具。为了确保用户有视觉反馈,我想将其与进度条相关联。
到目前为止我在这里:
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
,所以我可以更新它。
根据this,它与exec_ main
循环有关,但显然这里有一些我不明白的地方,因为我在[=16]之后调用my_operations
=].
不用说,我是初学者。有人有想法吗? 干杯
每个 GUI 都存在于一个事件循环中,允许您处理用户事件、OS 等事件,例如鼠标、键盘等,因此如果您阻止此处理 GUI不会更新它的状态,在你的情况下,问题是由 time.sleep()
引起的,它正在阻塞,阻止 GUI 激活显示 window 的状态。所以作为一个基本规则:不要在 GUI 的主线程中使用 time.sleep()
,我想 time.sleep()
模拟一个需要一定时间的任务,在这种情况下你必须从另一个线程执行这个任务如果你想更新 GUI,你必须通过信号来完成,它不应该直接完成。
在下面的示例中,我将使用 threading.Thread()
创建一个新线程和一个更新 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()