Приложение pyqt5, которое запускает параллельную функцию в фоновом режиме - PullRequest
0 голосов
/ 19 января 2020

Мне нужно построить простую программу, использующую pyqt5, которая печатает случайное число в поле lineEdit. Чтобы запустить программу, нужно нажать кнопку Run. Каждые три секунды генерируется новое случайное число, и мы его перепечатываем.

Однако, программа кажется заблокированной из-за функции 3 секунд удержания . Я использую функцию partial, определенную в functools, чтобы запустить этот процесс в фоновом режиме, но он не работает должным образом.

Отображается экран печати программы, а также код ниже:

enter image description here

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
import numpy as np
import time
from functools import partial

class RandomGen(object):
    number = None
    def run(self, lineEdit):
        while True:
             self.number = np.random.rand()
             lineEdit.setText("XXX")
             print(self.number)
             time.sleep(3);

class Ui_Dialog(object):
    counter_val = 0
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(321, 220)

        self.lineEdit = QtWidgets.QLineEdit(Dialog)
        self.lineEdit.setGeometry(QtCore.QRect(100, 30, 113, 21))
        self.lineEdit.setObjectName("lineEdit")

        self.lineEdit = QtWidgets.QLineEdit(Dialog)
        self.lineEdit.setGeometry(QtCore.QRect(100, 70, 113, 21))
        self.lineEdit.setObjectName("lineEdit")

        self.pushButton = QtWidgets.QPushButton(Dialog)
        self.pushButton.setGeometry(QtCore.QRect(100, 110, 113, 32))
        self.pushButton.setObjectName("pushButton")

        self.pushButton2 = QtWidgets.QPushButton(Dialog)
        self.pushButton2.setGeometry(QtCore.QRect(100, 160, 113, 32))
        self.pushButton2.setObjectName("pushButton")

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.pushButton.setText(_translate("Dialog", "Run"))
        self.pushButton2.setText(_translate("Dialog", "Counter"))

        self.pushButton.clicked.connect(partial(self.runner))
        self.pushButton2.clicked.connect(self.counter)

    def runner(self):
        rand = RandomGen()
        rand.run(self.lineEdit)

    def counter(self):
        self.lineEdit.setText(str(self.counter_val))
        self.counter_val = self.counter_val + 1

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Dialog = QtWidgets.QDialog()
    ui = Ui_Dialog()
    ui.setupUi(Dialog)
    Dialog.show()
    sys.exit(app.exec_())

Ответы [ 2 ]

1 голос
/ 19 января 2020

Я не думаю, что функция partial делает то, что вы думаете, она делает.

partial позволяет вам указать некоторые аргументы в функции без ее фактического вызова, например

from functools import partial

def multiplier(x, y)
    """a function to multiple 2 values together"""
    return x * y

# I can use partial to create a function that doubles values by
# partially specify the arguments to multiplier
doubler = partial(multiplier, 2) 

doubler(4) # This returns 8
1 голос
/ 19 января 2020

while True и time блокируют GUI.

. Вам нужно - Класс QTimer предоставляет повторяющиеся и одиночные таймеры.

from PyQt5 import QtCore, QtGui, QtWidgets
#from PyQt5.QtCore import *
import numpy as np
#import time
#from functools import partial


class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(321, 220)

        self.lineEdit = QtWidgets.QLineEdit(Dialog)
        self.lineEdit.setGeometry(QtCore.QRect(100, 30, 113, 21))
        self.lineEdit.setObjectName("lineEdit")

        self.lineEdit_2 = QtWidgets.QLineEdit(Dialog)                   # lineEdit_2
        self.lineEdit_2.setGeometry(QtCore.QRect(100, 70, 113, 21))
        self.lineEdit_2.setObjectName("lineEdit_2")

        self.pushButton = QtWidgets.QPushButton(Dialog)
        self.pushButton.setGeometry(QtCore.QRect(100, 110, 113, 32))
        self.pushButton.setObjectName("pushButton")

        self.pushButton2 = QtWidgets.QPushButton(Dialog)
        self.pushButton2.setGeometry(QtCore.QRect(100, 160, 113, 32))
        self.pushButton2.setObjectName("pushButton")

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.pushButton.setText(_translate("Dialog", "Run"))
        self.pushButton2.setText(_translate("Dialog", "Counter"))


class Dialog(QtWidgets.QDialog, Ui_Dialog):
    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)
        self.setupUi(self)

        self.counter_val = 0                                               # +
        self.pushButton.clicked.connect(self.runner)
        self.pushButton2.clicked.connect(self.counter)

        self.v_layout = QtWidgets.QVBoxLayout(self)
        self.v_layout.addWidget(self.lineEdit)
        self.v_layout.addWidget(self.lineEdit_2)
        self.v_layout.addWidget(self.pushButton)
        self.v_layout.addWidget(self.pushButton2)

    def runner(self):
        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.update_func)
        self.timer.start(3000)

    def counter(self):
        self.lineEdit_2.setText(str(self.counter_val))
        self.counter_val = self.counter_val + 1     

    def update_func(self):
        number = np.random.rand()
        self.lineEdit.setText(str(number))
#        print(number)


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = Dialog()
    w.show()
    sys.exit(app.exec_())

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...