2017-08-02 156 views
0

上下文: 我正在用python創建一個圖形界面與Qt創建器和「行爲」文件。我的GUI的測試版本是:如何暫停一個線程(python)

the test GUI

預期的行爲: 我正在運行其被以不同的輸入參數相同功能的2個不同的線程。使用SELECTOR按鈕,我可以將1或2的值分配給一個變量(並顯示它)。 按鈕啓動線程啓用正確的線程(第一次)。 通過修改全局的running變量,應通過停止按鈕關閉循環。 這是我的代碼

# -*- coding: utf-8 -*- 

from PyQt4 import QtCore, QtGui, uic 
import sys 
import threading 
import time 
import Queue 

running = False 
first_thread = None 
second_thread = None 
form_class = uic.loadUiType("simple2.ui")[0] 
q = Queue.Queue() 
select = 0 


def action(string, queue): #function called by threads 
    global running 
    while(running): 
     phrase = string  
     if queue.qsize() < 10: 
      queue.put(phrase) 
     #else: 
     # print queue.qsize() 

class MyWindowClass(QtGui.QMainWindow, form_class): 
    def __init__(self, parent=None): 
     QtGui.QMainWindow.__init__(self, parent) 
     self.setupUi(self) 

     #buttons   
     self.startButton.clicked.connect(self.start_clicked) 
     self.stopButton.clicked.connect(self.stop_clicked) 
     self.selector.clicked.connect(self.sel_click) 
     #variables 
     self.first = False 
     self.second = False 
     #queue 
     self.timer = QtCore.QTimer(self) 
     self.timer.timeout.connect(self.update_phrase) 
     self.timer.start(1) 

    def start_clicked(self): #start button callback 
     global select 
     if select > 0: 
      global running 
      running = True 
      print "started" 
      if (not self.first) & (select == 1): 
       first_thread.start() 
       self.first = True 
      if (not self.second) & (select == 2): 
       second_thread.start() 
       self.second = True 
      self.startButton.setEnabled(False) 
      self.startButton.setText('Starting...') 

    def stop_clicked(self): #stop button callback 
     global running 
     running = False 
     print "stopped" 
     self.startButton.setEnabled(True) 
     self.startButton.setText('Start Thread') 

    def sel_click(self): #selector button callback 
     global select 
     if select < 2: 
      select = select + 1 
     else: 
      select = 1 
     self.thread_counter.setText(str(select)) 

    def update_phrase(self): #looping function 
     global running 
     if (not q.empty()) & running: 
      self.startButton.setText('Thread on') 
      abc = q.get() 
      print abc 


    def closeEvent(self, event): 
     global running 
     running = False 

if __name__ == "__main__": 
    first_thread = threading.Thread(target=action, args = ("first", q)) 
    second_thread = threading.Thread(target=action, args = ("second", q)) 
    app = QtGui.QApplication(sys.argv) 
    w = MyWindowClass(None) 
    w.setWindowTitle('Multiple threads test in python') 
    w.show() 
    app.exec_() 

現在,每個線程應該在終端他們的論點簡單的print(「第一」或「第二」)。 如果第一次啓動線程,我的代碼就可以工作。但我想在無限次的線程之間切換。

由於線程無法停止,有沒有辦法「暫停」它們?

我找不到解決方案,我希望有人會幫我一段代碼。謝謝你在前進

回答

1

您可以使用鎖類來做到這一點,一個簡單的例子是:

import threading 

lock = threading.Lock() 

//here it will be lock 
lock.acquire() # will block if lock is already held 
    ... 

然後在另一側做

//this will wake up 
lock.release() 

,你可以在這裏閱讀更多http://effbot.org/zone/thread-synchronization.htm

+0

謝謝你的回答。請問我應該在哪裏放置鎖定命令?我應該把它們放到按鈕的開始/停止回調中,但它似乎是錯誤的。鎖類看起來是我需要的,但我仍然無法理解它是如何工作的。 – marcoresk

+0

@marcoresk沒關係,用多線程思考很困難,看看,我現在可以爲你提供線索,我在工作,但肯定的是,lock.acquiere()方法將在函數stopThread()中進行,然後你必須有另外一個線程在「偵聽」start()函數,你必須對互斥量做一些研究,以及一般的併發編程,線程和鎖,希望我能多幫一點點 –