【问题标题】:Tkinter - button command and gui blocksTkinter - 按钮命令和 gui 块
【发布时间】:2013-06-30 19:48:54
【问题描述】:

我正在尝试开始使用 tkinter 来设计一些图形界面,但实际上我遇到了一个问题...

这是我的小代码:

    #!/usr/bin/python3
# -*- coding: utf-8 -*-


# imports
from premier import *
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
from time import *


# init var
varstop=False


# functions
def launch():
    """search first numbers between 2 and var entry"""
    listbox.delete(0, "end") # clear listbox
    itime=time() # init time
    n=entry.get() # get limit

    if n.isnumeric()==False or int(n)<2:
        # check inputs
        messagebox.showwarning("", "insert an integer (>=2) on the entry")  
    else:
        stop_button["state"]="normal"
        launch_button["state"]="disabled"

        n=int(n)
        i=2
        nb=0 # count number of first numbers
        varprogress=0 # var of the progress bar
        global varstop

        while i<=n:
            if varstop==True:
                # if click on stop button, stop
                varstop=False
                return
            else:
                if premier(i)==True:
                    nb+=1
                    listbox.insert("end", " "+str(i))
                varprogress=int((i*100/n)-varprogress+1)
                progress.step(varprogress)
                i+=1

        listbox.insert("end", " number of first number between 1 and "+str(n)+": "+str(nb))
        temp=time()-itime
        listbox.insert("end", " process time: "+str(int(temp))+"s")
        stop_button["state"]="disabled"
        launch_button["state"]="normal"

def stop():
    global varstop
    varstop=True


# define gui
gui=Tk()
gui.title("Premier.py")

frame1=Frame(gui)
frame2=Frame(gui)
frame3=Frame(gui)

label=Label(frame1, text="Limit (>=2) :")
listbox=Listbox(frame2, height=25, width=50, selectmode="extended")
progress=ttk.Progressbar(frame3, length=350)
entry=Entry(frame1, width=25)
launch_button=Button(frame3, width=10, text="launch", command=launch)
stop_button=Button(frame3, width=10, text="stop", state="disabled")

# create gui
frame1.pack(expand=True)
frame2.pack(expand=True)
frame3.pack(expand=True)

label.pack(side="left")
entry.pack(side="right")
listbox.pack(side="left")
progress.pack(pady=5)
launch_button.pack(side="left", padx=50, pady=5)
stop_button.pack(side="right", padx=50, pady=5)

gui.mainloop()

当我点击启动按钮时,GUI 只是冻结,直到启动功能的“while”结束,我不知道为什么。 因此,例如,我无法管理我的进度条...

Here 是一个小视频...

你知道为什么 GUI 会这样冻结或者我该如何解决这个问题吗? 提前致谢

【问题讨论】:

标签: python python-3.x while-loop tkinter


【解决方案1】:

“为什么”是因为 Tkinter 是单线程的。当事件触发回调时,回调必须完成,然后才能处理更多事件。

为避免这种情况,您必须:

  1. 将耗时的代码移至另一个线程,或者
  2. 将耗时的代码移至另一个进程,或
  3. 将耗时的代码重构为可以通过事件循环在小迭代中完成的小片段,或者
  4. 作为一种低效且可能危险的解决方法,请在每次循环迭代后调用 update_idletasks,这至少允许处理“空闲”事件(例如重绘 GUI)

【讨论】:

  • 你认为更容易的选择是什么?
  • 但是您似乎说它有点冒险,而且它无法与用户交互......那么,1,2和3之间更简单的方法是什么?
猜你喜欢
  • 2021-04-14
  • 2023-02-24
  • 1970-01-01
  • 2020-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-10
  • 2021-07-08
相关资源
最近更新 更多