2

The context: I'm building a Graphical Interface with Qt creator and the "behaviour" file in python. A test version of my GUI is:

the test GUI

The expected behaviour: I am running 2 different threads which are referred to the same function with different input arguments. With the SELECTOR button I can assign the value of 1 or 2 to a variable (and display it) The button Start thread enables the correct thread to start (the first time). The loop should be turned off by the stop button by modifying the global running variable. This is my code

# -*- 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_()

For now, each thread should simple print on terminal their arguments ("First" or "Second"). If threads are started for the first time, my code works. But I would like to switch between threads infinite times.

Since threads cannot be stopped, is there a way to "pause" them?

I cannot find a solution, I hope someone will help me also with a piece of code. Thank you in advance

1 Answer 1

2

You can use Lock class to do that, a simple example would be:

import threading

lock = threading.Lock()

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

then in other side do

//this will wake up
lock.release()

you can read more here http://effbot.org/zone/thread-synchronization.htm

2
  • Thank you for the answer. May I ask where exactly should I put the lock commands? I supposed to put them into the start/stop callbacks of buttons, but it seems to be wrong. Lock class seems what I need, but I can't still understand how it could work in my case.
    – marcoresk
    Aug 2, 2017 at 17:57
  • @marcoresk It's ok, it's hard thinking with multi-threding, look, I can give you leads for now, I'm at work, but for sure, the method lock.acquiere() will go in the function stopThread(), at the end of it, and then you must have another thread "listening" for the start() function, you have to do a little research about mutex, and concurrent programming, threads and locks in general, hope I could help a little more Aug 2, 2017 at 18:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.