简体   繁体   English

使用“线程”模块制作开关按钮以执行 while 循环

[英]Making a switch button using "threading" module for executing while loop

I want to make program which a has button, when we click on button, it will run some functions infinitely and the button turn into another button such that when we click it second time, it will stop the infinite process.我想制作一个有按钮的程序,当我们点击按钮时,它会无限运行一些功能,按钮变成另一个按钮,这样当我们第二次点击它时,它会停止无限过程。 In my codes you can see my aim.在我的代码中你可以看到我的目标。

When i do not click on button, there is a text on button such as "start", and when i click first time, it starts an infinite process such as printing two functions.当我不点击按钮时,按钮上有一个文本,例如“开始”,当我第一次点击时,它会启动一个无限过程,例如打印两个函数。 After that, the button turn into a red color button which has text "stop" and when you click it second time, it stops this infinite while loop.之后,该按钮变成一个红色按钮,上面有文字“停止”,当您第二次单击它时,它会停止这个无限循环。

What I want: I want to convert my button into a switch such that when i click it second time, it stop the process, but be ready for running it again.我想要什么:我想把我的按钮转换成一个开关,这样当我第二次点击它时,它会停止这个过程,但准备好再次运行它。 What i meant is that when i click it second time, it stop the process and its color be green and text = "start", again.I want this clicking process foreover such as a switch of a lamb.When you click it, it will be ready for the other process.我的意思是,当我第二次点击它时,它停止了这个过程,它的颜色是绿色,文本 =“开始”,再次。我想要这个点击过程 foreover 例如一只羊羔的开关。当你点击它时,它将为其他过程做好准备。

My problem: When i click the button second time, my code gives error.我的问题:当我第二次单击按钮时,我的代码出错。 It did not turn into "start" button again". Can you help me to fix it.它没有再次变成“开始”按钮。你能帮我修一下吗?

Note: I am beginner in "threading" module,so please be clear in your answers.注意:我是“线程”模块的初学者,所以请在你的回答中清楚。

MY CODE:我的代码:

from tkinter import *
from tkinter import ttk
import threading
class Uygulama(object):
    def __init__(self):
        self.araclar()
    def araclar(self):
        self.etiket1 = Label(text="WELCOME TO HERE", fg="blue", font="Times 15 bold", 
                      bg="grey")
        self.etiket1.pack()
        
        self.stop_event = threading.Event()
        self.thread = threading.Thread(target=self.start, args=(self.stop_event,))
        self.dugme1 = Button( text="Start Greeting", command=self.start_cmd, 
                             fg="black", bg="green", font="bold")
        self.dugme1.place(relx=0.05, rely=0.65)

        self.etiket3 = Label(font="Times 14 bold", bg="grey")
        self.etiket3.place(rely=0.30, relx=0.08)

    def say_hello(self):
        print("Hello there")

    def say_hi(self):
        print("hi there")

    def start_cmd(self):
        self.dugme1.config(text="Stop greeting", command=self.stop_cmd,fg="black", bg="red", 
                             font="bold")
        self.thread.start()

    def stop_cmd(self):
        self.stop_event.set()
        self.destroy()

    def start(self, stop_event):
        self.etiket3.config(text="You are greeting them !",  font="Times 17 bold")                              
        while not stop_event.is_set():
            self.say_hello()
            self.say_hi()

pencere = Tk()
pencere.geometry("500x500+400+30")
pencere.resizable(width=False, height=False)
pencere.configure(bg="grey")
uyg = Uygulama()
mainloop()

The error:错误:

Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.10/tkinter/__init__.py", line 1921, in __call__
  return self.func(*args)
File "/home/sunw/Desktop/uygulama.py", line 34, in stop_cmd
  self.destroy()
AttributeError: 'Uygulama' object has no attribute 'destroy'

** ADDING DESTROY:** ** 添加销毁:**

def destroy(self):
    self.dugme1.config(text="Start Greeting", command=self.start_cmd,
                       fg="black", bg="green", font="bold")

New error:新错误:

Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.10/tkinter/__init__.py", line 1921, in __call__
 return self.func(*args)
File "/home/sunw/Desktop/uygulama.py", line 35, in start_cmd
  self.thread.start()
File "/usr/lib/python3.10/threading.py", line 930, in start
 raise RuntimeError("threads can only be started once")
RuntimeError: threads can only be started once

As explained, not sure what was the purpose for self.destroy(), just remove that.如前所述,不确定 self.destroy() 的目的是什么,只需将其删除即可。

Also threads once defined can be started only once, see https://bugs.python.org/issue751260此外,一旦定义的线程只能启动一次,请参见https://bugs.python.org/issue751260

Remove self.thread declaration from araclar, and have start and stop functions as below:从 araclar 中删除 self.thread 声明,并具有启动和停止功能,如下所示:

def start_cmd(self):
    self.dugme1.config(text="Stop greeting", command=self.stop_cmd, fg="black", bg="red",
                       font="bold")
    self.stop_event.clear()
    threading.Thread(target=self.start, args=(self.stop_event,)).start()

def stop_cmd(self):
    self.stop_event.set()
    self.dugme1.config(text="Start Greeting", command=self.start_cmd,
                         fg="black", bg="green", font="bold")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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