Обновление индикатора выполнения из внешнего скрипта - PullRequest
0 голосов
/ 21 ноября 2018

Я пытаюсь обновить индикатор выполнения PyQt4 в реальном времени из внешнего скрипта python, так как этот внешний скрипт проходит через свои циклы.До сих пор я приводил минимальный рабочий пример моего прогресса;Может кто-нибудь, пожалуйста, наставьте меня на лучшие практики в будущем?

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) печатается на терминале.

1 Ответ

0 голосов
/ 21 ноября 2018

У вас есть циклический импорт, который вызывает бесконечный цикл, поскольку 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_())
...