第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

工作線程和主窗口之間的 PyQt5 信號(hào)通信無(wú)法正常工作

工作線程和主窗口之間的 PyQt5 信號(hào)通信無(wú)法正常工作

守候你守候我 2021-07-23 14:04:10
我正在使用 PyQt5 創(chuàng)建一個(gè)應(yīng)用程序,它有一個(gè)非常簡(jiǎn)單的用戶界面。有一個(gè)可以從中選擇值的下拉列表,然后有一個(gè)可以單擊的按鈕,將根據(jù)下拉列表中的當(dāng)前值執(zhí)行操作。目前,如果我運(yùn)行下面的代碼,我可以從下拉列表中獲取一個(gè)值,它會(huì)在myaction.myaction(customer_name)運(yùn)行之前發(fā)送到工作線程。代碼也運(yùn)行良好,但是當(dāng)工作線程中的函數(shù)運(yùn)行時(shí),GUI 沒(méi)有按照我希望的方式工作。當(dāng)我單擊開(kāi)始按鈕時(shí),它應(yīng)該向 GUI 發(fā)出一個(gè)信號(hào)以禁用該按鈕、更改其標(biāo)簽和顏色,但這從未發(fā)生過(guò)。當(dāng)函數(shù)完成時(shí),它應(yīng)該變回原來(lái)的形式。問(wèn)題是我如何處理信號(hào),還是我的類中有多余的功能?每次單擊按鈕時(shí)將該下拉列表值發(fā)送到工作線程的正確方法是什么,所以我可以簡(jiǎn)單地將它用作變量?我在網(wǎng)上找到的每一個(gè)可能的解決方案都讓我興奮,但他們都沒(méi)有為我工作,或者他們中的一些讓我無(wú)法理解。
查看完整描述

2 回答

?
蕪湖不蕪

TA貢獻(xiàn)1796條經(jīng)驗(yàn) 獲得超7個(gè)贊

這個(gè)問(wèn)題是由一個(gè)非常普遍和錯(cuò)誤的概念引起的,他們認(rèn)為 QThread 是一個(gè)Qt Thread,即Qt創(chuàng)建的新線程,但不,QThread文檔中指出的線程處理程序

QThread 類提供了一種與平臺(tái)無(wú)關(guān)的方法來(lái)管理線程。

QThread 對(duì)象管理程序中的一個(gè)控制線程。QThreads 在 run() 中開(kāi)始執(zhí)行。默認(rèn)情況下,run() 通過(guò)調(diào)用 exec() 啟動(dòng)事件循環(huán),并在線程內(nèi)運(yùn)行 Qt 事件循環(huán)。

在另一個(gè)線程上運(yùn)行的唯一部分是 run 方法,在您的情況下,您沒(méi)有調(diào)用,因?yàn)槟倪壿嫴煌?,您不想連續(xù)執(zhí)行繁重的任務(wù),但應(yīng)用戶的要求,因此設(shè)計(jì)必須是worker 但您使用 QThread 作為基類,這是不正確的,您必須使用 QObject 作為基類并將其移動(dòng)到新線程,以便 QObject 在該線程中執(zhí)行其任務(wù),防止 GUI 阻塞。

一個(gè) QObject 不是線程安全的,它存在于一個(gè)線程中,它所在的線程由以下決定:

  • AQObject住在父線程中

  • 如果您沒(méi)有父級(jí),請(qǐng)留在創(chuàng)建它的線程中,除非您已移動(dòng)到另一個(gè)線程。

  • 并且您可以使用該moveToThread()函數(shù)移動(dòng)到另一個(gè)線程,但是moveToThread()如果它QObject有父級(jí),因?yàn)榈谝粋€(gè)條件是特權(quán)的,則會(huì)失敗。

另一方面,如果您想從另一個(gè)線程調(diào)用一個(gè)方法,則有必要使用裝飾器 @QtCore.pyqtSlot()


綜上所述,我們得到以下解決方案:

#!/usr/bin/env python3

import sys

import time

from PyQt5 import QtCore, QtWidgets



class ConfWorker(QtCore.QObject):

    updated_button = QtCore.pyqtSignal(list)

    updated_label = QtCore.pyqtSignal(str)

    updated_error = QtCore.pyqtSignal(str)

    request_signal = QtCore.pyqtSignal()

    customer = QtCore.pyqtSignal(str)


    def __init__(self, parent=None):

        super(ConfWorker, self).__init__(parent)

        self.customer.connect(self.getcustomer)


    @QtCore.pyqtSlot()

    def doWork(self):

        self.request_signal.emit()


    @QtCore.pyqtSlot(str)

    def getcustomer(self, text):

        self.configure(text)


    def configure(self, customer_name):

        self.updated_button.emit(["In progress...", False])

        self.updated_label.emit(customer_name)

        time.sleep(5) # During this time you should be able to see color change etc.

        #myaction.myaction(customer_name)# TAKES ~20 SECONDS TO FINISH

        self.updated_button.emit(["Start", True])


class ConfGUI(QtWidgets.QWidget):

    def __init__(self, parent=None):

        super(ConfGUI, self).__init__()


        # create a QThread and start the thread that handles

        thread = QtCore.QThread(self)

        thread.start()


        # create the worker without a parent so you can move

        self.worker = ConfWorker()

        # the worker moves to another thread

        self.worker.moveToThread(thread)


        self.worker.updated_button.connect(self.updateButton)

        self.worker.updated_label.connect(self.updateLabel)

        self.worker.updated_error.connect(self.updateError)

        self.worker.request_signal.connect(self.sendCustomer)


        self.targetBtn = QtWidgets.QPushButton('Start Configuration', self)

        self.targetBtn.setStyleSheet("QPushButton { background-color: green; color: white }"

                        "QPushButton:disabled { background-color: red; color: white }")

        self.targetBtn.clicked.connect(self.worker.doWork)

        self.targetBtn.setFixedSize(200, 50)


        self.customerlist = QtWidgets.QComboBox(self)

        self.customerlist.addItems(["testcustomer1", "testcustomer2", "testcustomer3"])

        self.customerlist.setFixedSize(200, 50)


        self.label = QtWidgets.QLabel(self, alignment=QtCore.Qt.AlignCenter)

        self.label.setStyleSheet('font-size: 30pt; font-family: Courier; color: green;')

        self.label.setFixedSize(400,50)


        self.error_label = QtWidgets.QLabel(self, alignment=QtCore.Qt.AlignCenter)

        self.error_label.setStyleSheet('font-size: 30pt; font-family: Courier; color: red;')

        self.error_label.setFixedSize(400,50)


        lay = QtWidgets.QVBoxLayout(self)

        lay.addWidget(self.customerlist, alignment=QtCore.Qt.AlignCenter)

        lay.addWidget(self.label, alignment=QtCore.Qt.AlignCenter)

        lay.addWidget(self.error_label, alignment=QtCore.Qt.AlignCenter)

        lay.addWidget(self.targetBtn, alignment=QtCore.Qt.AlignCenter)

        self.setFixedSize(400, 550)


    @QtCore.pyqtSlot()

    def sendCustomer(self):

        self.worker.customer.emit(self.customerlist.currentText())


    @QtCore.pyqtSlot(list)

    def updateButton(self, button_list):

        self.targetBtn.setText(button_list[0])

        self.targetBtn.setEnabled(button_list[1])


    @QtCore.pyqtSlot(str)

    def updateLabel(self, label_text):

        self.label.setText(label_text)


    @QtCore.pyqtSlot(str)

    def updateError(self, error_text):

        self.error_label.setText(error_text)



if __name__ == '__main__':

    app = QtWidgets.QApplication(sys.argv)

    ex = ConfGUI()

    ex.show()

    sys.exit(app.exec_())

觀察:另外,正如您在我的解決方案中看到的那樣,QThread將是窗口的子級(jí),因?yàn)镼Thread是QObject處理另一個(gè)線程。


查看完整回答
反對(duì) 回復(fù) 2021-07-28
?
FFIVE

TA貢獻(xiàn)1797條經(jīng)驗(yàn) 獲得超6個(gè)贊

你真的寫(xiě)了很困難很簡(jiǎn)單的事情。嘗試一下:


import sys

from PyQt5.QtWidgets import QWidget, QApplication, QPushButton, QComboBox, QLabel

from PyQt5.QtCore    import QThread, pyqtSignal


class ConfWorker(QThread):

    threadSignal = pyqtSignal(str)

    finishSignal = pyqtSignal(str)


    def __init__(self, startParm):

        super().__init__()

        self.startParm = startParm   # Initialize the parameters passed to the task 


    def run(self):

        # Do something...

        for i in range(20):

            text = "In progress ................." \

                    if i%2==0 else "In progress {}".format(self.startParm)

            self.threadSignal.emit(text)

            QThread.msleep(500)

        self.finishSignal.emit(self.startParm)



class ConfGUI(QWidget):

    def __init__(self):

        super().__init__()

        self.setGeometry(800, 100, 400, 550)

        self.setFixedSize(400, 550)        


        self.targetBtn = QPushButton('Start Configuration', self)

        self.targetBtn.setStyleSheet(

                        "QPushButton { background-color: green; color: white;}"

                        "QPushButton:disabled { background-color: red; color: white;}"

                        )

        self.targetBtn.setGeometry(100, 400, 200, 50)

        self.targetBtn.clicked.connect(self.workerStart)           


        self.customerlist = QComboBox(self)

        self.customerlist.setGeometry(100, 50, 200, 50)

        self.customerlist.setObjectName("customer")

        self.customerlist.addItem("testcustomer1")

        self.customerlist.addItem("testcustomer2")

        self.customerlist.addItem("testcustomer3")

        self.customerlist.activated[str].connect(self.comboActivated)

        self.startParm = "testcustomer1"


        self.label = QLabel(self)

        self.label.setStyleSheet('font-size: 30pt; font-family: Courier; color: green;')

        self.label.setGeometry(70,250,400,50)


    def workerStart(self):

        self.targetBtn.setText("In progress...")

        self.targetBtn.setEnabled(False)

        self.label.setText("")

        self.worker = ConfWorker(self.startParm)  

        self.worker.threadSignal.connect(self.on_threadSignal)

        self.worker.finishSignal.connect(self.on_finishSignal)        

        self.worker.start()                     


    def on_threadSignal(self, text):

        self.targetBtn.setText(text)


    def on_finishSignal(self, text):

        self.targetBtn.setEnabled(True)

        self.targetBtn.setText("Start Configuration'")

        self.label.setText(text)


    def comboActivated(self, text):

        self.startParm = text



if __name__ == '__main__':

    app = QApplication(sys.argv)

    ex  = ConfGUI()

    ex.show()

    sys.exit(app.exec_())

http://img1.sycdn.imooc.com//610141d50001bb6a04000582.jpg

查看完整回答
反對(duì) 回復(fù) 2021-07-28
  • 2 回答
  • 0 關(guān)注
  • 461 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)