1. 程式人生 > >pyqt通過訊號槽機制來退出執行緒

pyqt通過訊號槽機制來退出執行緒

剛剛解決了pyqt執行緒退出問題,特來此記錄下解決的想法。以下用一個簡單例子來表現如何用signal/slot訊號槽來退出執行緒。

若有一個按鈕,點選開始執行緒,再次點選退出執行緒,執行緒的工作為列印a(1-20)然後b(1-20),執行緒程式碼如下:

class UpdateThread(QThread):
    def __init__(self, parent=None):
        super(UpdateThread, self).__init__(parent)
        self.flag = 1# 用來判斷迴圈是否繼續的標誌,通過改變該標誌來使得執行緒中run函式退出

    def run(self):
        table = ['a', 'b', 'c', 'd ', 'e', 'f', 'g']
        for i in range(6):
            if self.flag == 1:
                print table[i]
                for m in range(20):
                    print m
                    time.sleep(0.5)
            else:
                break
        print 'close'# 輸出標明執行緒run函式已經退出

    def stop(self):
        print 'setting flag false'
        self.flag = 0
        print self.flag
一開始因為python的threading沒有執行緒退出的api,瞭解到QThread有實現執行緒的阻塞,退出,強制退出等api,於是就將執行緒繼承了QThread,但是在gui介面的按鈕邏輯中寫上mythread.wait()或者是quit()還是terminate()都無法對執行緒產生影響(可能是當時沒有使用訊號槽機制,所以不起作用),然後自己來寫一個stop函式用來修改執行緒中的一個標誌,使得run函式中的迴圈停止,然後就如上程式碼所示,在按鈕邏輯中如下所寫(錯誤示範):
def update_db():# error
            self.new_thread1 = UpdateDbThread()
            if self.update_tag == 0:
                self.update_tag = 1
                self.new_thread1.start()
            else:
                self.update_tag = 0
                self.new_thread1.stop()

執行之後發現stop函式雖然改變了self.flag的值,但是迴圈中判斷語句中flag的值依然為1,迴圈並沒有停止,然後就去查閱資料,以及上stackoverflow尋找答案,最終知道了執行緒需要通過訊號槽機制來響應,所以便去查閱qt的signal/slot的相關資訊,修改按鈕程式碼如下:

class mywidget(Qwidget): 
       sin = pyqtSignal()# 提前申明
       def __init__(self):
         ...
       self.new_thread1 = UpdateDbThread()
       self.sin.connect(self.new_thread1.stop)
def update_db():
       if self.update_tag == 0: 
           self.update_tag = 1
           self.new_thread1.start() 
       else: 
           self.update_tag = 0 
           self.sin.emit()


</pre><p></p><pre>

pyqtSignal訊號的定義不可以寫在update_db方法中,也不可以寫在init()初始化方法中,原因如下(來自stackoverflow):


所以我們就在init方法之前定義好訊號sin,然後連線上執行緒的stop方法。點選按鈕傳送訊號,就好改變執行緒的標誌,然後從迴圈中退出,執行結果如下:

為了便於貼圖,我將迴圈輸出改為了10:

執行緒正常退出,目標達成。可以根據自己的需要重寫run方法。

還有需要注意的是,不可以在方法中寫上 mythread = update_db() ,這樣在執行時會報錯,destroyed while thread is running,因為在方法中mythread是一個區域性變數,當方法結束時,python的垃圾回收機制就會自動銷燬,然後就會出現以上錯誤,所以必須在mythread的前面加上self,使得執行緒成為全域性變數。

如需轉載,向本人說明後,經過同意方可,轉載附加上本文章原地址。

相關推薦

pyqt通過訊號機制退出執行

剛剛解決了pyqt執行緒退出問題,特來此記錄下解決的想法。以下用一個簡單例子來表現如何用signal/slot訊號槽來退出執行緒。 若有一個按鈕,點選開始執行緒,再次點選退出執行緒,執行緒的工作為列印a(1-20)然後b(1-20),執行緒程式碼如下: class Upd

QNetworkAccessManager不使用訊號/機制獲得QNetworkReply的解決辦法

正在做一個第三方微信企業要介面的專案,JAVA的實現方法比較簡單,網上資料也很多。 但是我需要在C++下實現,微信企業號介面大多都是https的GET/POST方法實現的。 Qt提供了一個封裝好的類QNetworkAccessManager,就不需要使用windows的套接

Qt訊號機制原始碼學習

簡述 這裡並不全面介紹Qt的訊號槽機制的實現,僅以qt-opensource-windows-x86-msvc2015_64-5.6.0的原始碼為原料,以一個簡單的訊號槽例子為點,打通一條線。下面的原始碼大部分是經過刪減和修改的,為了使原始碼更簡單並且增加可讀性。 簡單的訊號槽例子

QT signal/slot訊號機制

Pyqt5系列(七)-訊號與槽機制 PyQt訊號與槽之訊號與槽的入門應用(一) PyQt 5訊號與槽的幾種高階玩法 自定義訊號emit及傳參 自定義槽函式 PyQt訊號與槽之Qt Designer神助攻(五)-部落格全是pyQt 看文件 訊號的connect連線最好放在__init__解

Qt訊號機制對傳輸引數上的侷限性

訊號與槽機制是比較靈活的,但有些侷限性我們必須瞭解,這樣在實際的使用過程中做到有的放矢,避免產生一些錯誤。下面就介紹一下這方面的情況。 1.訊號與槽的效率是非常高的,但是同真正的回撥函式比較起來,由於增加了靈活性,因此在速度上還是有所損失。 當然這種損失相對來說是比較小的,通過在一臺i5

Qt 5 在外掛中如何使用訊號機制

對於一個大型系統,如何保證可擴充套件性和可維護性是十分重要的。Qt為我們提供了一套外掛系統,能夠較好的解決擴充套件性的問題。但是在將外掛系統與訊號槽機制相結合的過程中,也遇到了一些問題。經過一番探索之後總算成功了,這裡寫一個小小的教程,供有需要的同學查閱。 一、概述 Qt

程序間的訊號 --------詳解(通過訊號去控制程序的執行狀態)

(1)概述   1.訊號是一種軟體中斷,用來處理非同步事件   2.訊號的本質是一種程序間的通訊,一個程序向另一個程序傳送訊號   3.執行kill -l可檢視系統所有的訊號   4.作用:ctl+c時用來做一些收尾工作:      1.刪除管道.刪除共享記憶體.刪除訊號量.刪除訊息佇列..    

Qt 之 訊號機制及優缺點

1. Qt 訊號槽機制 概念: 訊號槽是 Qt 框架引以為豪的機制之一。所謂訊號槽,實際就是觀察者模式。當某個事件發生之後,比如,按鈕檢測到自己被點選了一下,它就會發出一個訊號(signal)。這種發出是沒有目的的,類似廣播。如果有物件對這個訊號感興趣,它就會使用連線(connect)函

用 QueueUserAPC() 函式強制執行退出等待狀態

         當系統建立一個執行緒的時候,會同時建立一個與執行緒相關的佇列。這個佇列被成為非同步過程呼叫(APC)佇列。同時我們也知道,windows提供了6個函式可以等待並將執行緒設定為可提醒狀態--------- SleepEx(),WaitForSingleObje

QT 訊號不在同一個執行 connect

主執行緒中發出一個訊號,另一個執行緒槽函式沒有響應,這個問題搞了好幾個小時,才發現原來是connect時候的第5個引數寫錯了,在這裡做下備註吧。 connect用於連線qt的訊號和槽,在qt程式設計過程中不可或缺。它其實有第五個引數,只是一般使用預設值,在滿足某些特殊需求

Qt中的訊號機制詳解

一、關於Qt 我們都知道Qt是一個用於做gui介面開發的框架,Qt擁有強大的元件開發機制,Qt同時也是一個跨平臺的C++介面開發框架,他和MFC不太一樣,MFC主要是專注於windows上的介面開發。Qt中比較有特點的東西也就是訊號槽機制,在講訊號槽機制之前,

從零開始實現訊號機制:二

好了,是時候寫段Qt程式碼看看了,這是一段典型的使用Qt訊號槽的程式碼,因為我們這段程式碼直接寫在main.cpp裡面,所以在最後記得加上#include "main.moc":#include <iostream> #include <QApplicati

Qt高階——Qt訊號機制原始碼解析

一、訊號槽機制的原理 1、訊號槽簡介 訊號槽是觀察者模式的一種實現,特性如下: A、一個訊號就是一個能夠被觀察的事件,或者

python 用threading中event實現執行同步

import threading import time event = threading.Event() #event.clear():將event的標誌設定為False,呼叫wait方法的所有執行緒將被阻塞; event.clear() def synchro_fun():

機制——解決多執行的資料共享帶來的同步問題

“非執行緒安全”——多個執行緒對同一個物件中的例項變數進行併發訪問時發生,產生的後果就是“髒讀”,也就是取到的資料其實是被更改過的。 1、方法內的變數為執行緒安全的 方法內部的私有變數,則不存在“非執行緒安全”的問題,所得結果也就是“執行緒安全”的。 2、例項變數非執行緒安全 如果多個執行緒

使用執行建立執行

1.如何使用執行緒池來建立執行緒? java中提供了一個靜態工廠方法來建立不同的執行緒池:  Executors 通過靜態方法創建出的執行緒都實現了ExecutorService介面。常用的方法包括: newFixedThreadPool(int threads); 建立

QThread 與 QObject的關係(QObject可以用於多執行,可以傳送訊號呼叫存在於其他執行的slot函式,但GUI類不可重入)

QThread 繼承 QObject.。它可以傳送started和finished訊號,也提供了一些slot函式。 QObject.可以用於多執行緒,可以傳送訊號呼叫存在於其他執行緒的slot函式,也可以postevent給其他執行緒中的物件。之所以可以這樣做,是因為每個執行

使用內部類執行隱藏在類中的幾種方法

class InnerThread1{ private int countDown=5; private Inner inner; private class Inner extends Thread{ Inner(String na

java 內部類執行 程式碼隱藏在類中

package org.rui.thread.basic; import java.util.concurrent.TimeUnit; /** * 有時通過使用內部類來將執行緒 程式碼隱藏在類中 將會很有用,就像下面這樣: * ----- * InnerThrea

哪幾種方式可用實現執行間通知和喚醒

從這三個方法的文字描述可以知道以下幾點資訊: 1)wait()、notify()和notifyAll()方法是本地方法,並且為final方法,無法被重寫。 2)呼叫某個物件的wait()方法能讓當前執行緒阻塞,並且當前執行緒必須擁有此物件的monitor(即鎖) 3)呼叫某個物件的notify()方