简体   繁体   中英

Python GUI Threading

I want to have a function run continuously within a tkinter GUI. I have attached some shell code:

#!/usr/bin/env python3

import tkinter as tk
from time import sleep
import os
import sys

class Application(Frame):

    def __init__(self, master):
        super(Application, self).__init__(master)
        self.grid()
        self.create_widgets()

        def create_widgets(self):
        ......

root = Tk()  

def run_continously:
    ... -- calls sleep -- ...
    root.after(3000, run_continuously)


root.geometry('%dx%d+%d+%d' % (w, h, x, y))
app = Application(root)
root.after(3000, run_continuously)          
root.mainloop()

When running the GUI it tends to run the 'run_continuously' function once and the GUI freezes up. I suspect from poking around that this is due to the sleep function (which I call in the run_continuously function)

How would I go about implementing the 'run_continuously' function in a very simple thread to get around this issue? Would running the function in a thread even get me around the problem? The 'run_continuously' function does not need to interact at all with the Application class. I want it to run simply in the background and stop when the mainloop is finished.

Here is the end of the code:

def run_continuously(quit_flag):
    print("in it")
    if not quit_flag:
        GPIO.output(DIR_PIN, True)
        for i in range(steps):
            print("in loop")
            GPIO.output(STEP_PIN, True)
            sleep(sDelay)
            GPIO.output(STEP_PIN, False)
            sleep(sDelay)
        sleep(wait_time)
        GPIO.output(DIR_PIN, False)    
        for i in range(steps):
            GPIO.output(STEP_PIN, True)
            sleep(sDelay)
            GPIO.output(STEP_PIN, False)
            sleep(sDelay)
            print("run motor")
        root.after(1000, run_continuously(quit_flag,))


#=================================================================
# main
#=================================================================

root = Tk()                            # Create the GUI root object
press1 = StringVar()
press2 = StringVar()

x = 275
y = 50
w = 580
h = 250


root.geometry('%dx%d+%d+%d' % (w, h, x, y))
app = Application(root)          # Create the root application window
quit_flag = False                
root.after(0, app.read_pressure)
motor_thread = threading.Thread(target=run_continuously, args=(quit_flag,)).start()
root.mainloop()
quit_flag=True
motor_thread.join()

This is a minimal, complete, and verifiable example that exits cleanly if the 'QUIT' button is pressed or Ctrl-C is pressed:

from Tkinter import *
import multiprocessing
import threading
import time
import logging


class Application(Frame):
    def create_widgets(self):
        self.quit_button = Button(self)
        self.quit_button['text'] = 'QUIT'
        self.quit_button['fg'] = 'red'
        self.quit_button['command'] = self.quit
        self.quit_button.pack({'side': 'left'})

    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.quit_button = None
        self.pack()
        self.create_widgets()
        self.poll()

    def poll(self):
        """
        This method is required to allow the mainloop to receive keyboard
        interrupts when the frame does not have the focus
        """
        self.master.after(250, self.poll)


def worker_function(quit_flag):
    counter = 0
    while not quit_flag.value:
        counter += 1
        logging.info("Work # %d" % counter)
        time.sleep(1.0)


format = '%(levelname)s: %(filename)s: %(lineno)d: %(message)s'
logging.basicConfig(level=logging.DEBUG, format=format)
root = Tk()
app = Application(master=root)
quit_flag = multiprocessing.Value('i', int(False))
worker_thread = threading.Thread(target=worker_function, args=(quit_flag,))
worker_thread.start()
logging.info("quit_flag.value = %s" % bool(quit_flag.value))
try:
    app.mainloop()
except KeyboardInterrupt:
    logging.info("Keyboard interrupt")
quit_flag.value = True
logging.info("quit_flag.value = %s" % bool(quit_flag.value))
worker_thread.join()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM