我正在尝试从外部python脚本实时更新PyQt4进度条,因为该外部脚本会通过其循环运行。到目前为止,我已经提供了一个最小的,可行的工作示例;谁能指导我有关未来的最佳做法?
GUI.py:
import sys, os
from pyface.qt import QtGui, QtCore
os.environ['ETS_TOOLKIT'] = 'qt4'
from traits.api import HasTraits,Instance,on_trait_change,Int
from traitsui.api import View,Item,VGroup
import external
#from PyQt4.QtCore import QThread
class P1(QtGui.QWidget):
def __init__(self, parent=None):
super(P1, self).__init__(parent)
layout = QtGui.QGridLayout(self)
def setProgress():
if P1.progress.value() == 0:
self.button.setDisabled(True)
self.button.setText('Computing Data')
external.op()
if P1.progress.value() == 100:
self.button_dist.setText('Data Complete')
self.button = QtGui.QPushButton('Compute Data', self)
self.connect(self.button, QtCore.SIGNAL('clicked()'), setProgress)
layout.addWidget(self.button, 1, 2, 1, 1)
self.button.setDisabled(False)
self.button.show()
P1.progress = QtGui.QProgressBar(self)
P1.progress.setMinimum = 0
P1.progress.setMaximum = 100
P1.progress.setValue(0)
layout.addWidget(P1.progress, 1, 3, 1, 3)
P1.progress.show()
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.window = P1(self)
self.setCentralWidget(self.window)
self.show()
if __name__ == '__main__':
app = QtGui.QApplication.instance()
w = MainWindow()
sys.exit(app.exec_())
external.py:
import sys, os, time
from pyface.qt import QtGui, QtCore
os.environ['ETS_TOOLKIT'] = 'qt4'
from GUI import P1
#from PyQt4.QtCore import QThread
def op():
for i in range(1, 101):
p1 = P1()
p1.progress.setValue(i)
time.sleep(0.01)
print(i)
为使此示例按我的预期工作,当您单击按钮Compute Data
时,进度栏的填充速度应与在终端机上打印i in range(1,101)
的速度相同。
答案 0 :(得分:1)
由于GUI导入到GUI的外部和外部,因此您有一个循环导入会导致无限循环,这是设计不良的征兆。另一方面,进度条必须是该类的成员。另外,外部任务必须在线程中执行,并且要更新它们,您必须使用将数据传输到GUI线程的信号。
external.py
import sys, os, time
from pyface.qt import QtGui, QtCore
os.environ['ETS_TOOLKIT'] = 'qt4'
def op(progress):
for i in range(1, 101):
progress.emit(i)
time.sleep(0.01)
print(i)
GUI.py
import sys, os
from pyface.qt import QtGui, QtCore
os.environ['ETS_TOOLKIT'] = 'qt4'
import threading
# from traits.api import HasTraits,Instance,on_trait_change,Int
# from traitsui.api import View,Item,VGroup
import external
class P1(QtGui.QWidget):
progressChanged = QtCore.Signal(int)
def __init__(self, parent=None):
super(P1, self).__init__(parent)
self.button = QtGui.QPushButton('Compute Data')
self.button.clicked.connect(self.start_task)
self.progress = QtGui.QProgressBar(minimum=0, maximum=100, value=0)
self.progressChanged.connect(self.on_progressChanged)
layout = QtGui.QGridLayout(self)
layout.addWidget(self.button, 1, 2, 1, 1)
layout.addWidget(self.progress, 1, 3, 1, 3)
@QtCore.Slot()
def start_task(self):
t = threading.Thread(target=external.op, args=(self.progressChanged, ), daemon=True)
t.start()
@QtCore.Slot(int)
def on_progressChanged(self, val):
self.progress.setValue(val)
if val == self.progress.maximum():
self.button.setDisabled(False)
self.button.setText('Data Complete')
else:
self.button.setText('Computing Data')
self.button.setDisabled(True)
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.window = P1()
self.setCentralWidget(self.window)
self.show()
if __name__ == '__main__':
app = QtGui.QApplication.instance()
if app is None:
app = QtGui.QApplication([])
w = MainWindow()
sys.exit(app.exec_())