簡體   English   中英

PyQt5 運行QMessageBox時異常退出

[英]PyQt5 Abnormal exit when running QMessageBox

我正在創建一個程序,它打開 IP 列表 csv 文件並在按下按鈕時執行 SNMP-GET。 但是,按下按鈕時,正常執行SNMP-GET,但顯示QMessageBox時程序異常結束。

def check_upgrade(self):
    for i in self.agw_num_list:
        send_snmp_get = getCmd(SnmpEngine()
                               , CommunityData(self.read_community, mpModel=1)
                               , UdpTransportTarget((self.ip_list[i-1], self.snmp_port), timeout=0.5, retries=1)
                               , ContextData()
                               , ObjectType(ObjectIdentity('1.3.6.1.4.1.8218.4.20.1.4.0'))
                               , ObjectType(ObjectIdentity('1.3.6.1.4.1.8218.4.20.5.2.0'))
                               )
        errorIndication, errorStatus, errorIndex, varBinds = next(send_snmp_get)

        if len(varBinds) != 0:
            encoding_pkg_version = str(varBinds[0][1]).encode()
            encoding_mgc_status = str(varBinds[1][1]).encode()
            pkg_version = encoding_pkg_version.decode()
            mgc_status = encoding_mgc_status.decode()

            result = str(i) + '   ' \
                     + str(self.ip_list[i-1]) \
                     + '   ' + str(errorIndication) \
                     + '   ' + str(pkg_version) \
                     + '   ' + str(mgc_status)
            self.display_result(result)

        else:
            result = str(i) + '   ' \
                     + str(self.ip_list[i-1]) \
                     + '   ' + 'NoReponse'
            self.display_result(result)

    self.upgrade_check_msgbox()

def upgrade_check_btn_clicked(self):
    self.result_textb.clear()
    t = threading.Thread(target=self.check_upgrade, daemon=True)
    t.start()

def upgrade_check_msgbox(self):
    if self.file_name == '':
        QMessageBox.warning(self, 'check', 'need file')
    else:
        QMessageBox.information(self, 'check', 'complete')

調用 self.check_upgrade function 而不生成線程時正常工作。

進程以退出代碼 -1073741819 (0xC0000005) 結束

您不能從創建QApplication的線程以外的線程調用 Qt Widget 內容。 這是一個無法繞過的硬性限制。

如果您需要執行 GUI 操作以響應線程上發生的某些事情,您必須將其發送回主線程事件循環,並讓主線程代表 worker 執行 GUI 操作。

通常,這可以通過讓主線程運行一個事件循環( QApplication.exec_() )來完成,或者通過發布一個自定義事件來由主線程上的 object “活動”處理,或者通過在一個屬於工作線程的QObject (= 在工作線程中創建,或使用moveToThread移動到那里),並將其連接到位於主線程中的 object 的插槽。 Qt 將負責在信號發出時通過事件循環分派信號。

這在瑣碎的情況下通常很容易做到,例如當您只需要知道一個工作人員是否已終止時,因為QThread已經具有線程結束時發出的相關信號。

另一種選擇是完全避免線程並使用 API 的異步版本(如果可用)。 在這種情況下,您仍然可以在主線程上運行事件循環,而不會在等待 SMTP 調用結束時阻塞它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM