【问题标题】:Show Progress Bar during a system call in tkinter在 tkinter 的系统调用期间显示进度条
【发布时间】:2015-06-29 14:41:46
【问题描述】:

我尝试从用户那里获得一些输入。我进行系统调用并在按下按钮时将输入作为参数传递(在本例中为 Next)。在此期间,我想在当前窗口中添加不确定的进度条小部件,直到系统调用返回某些内容并进入下一个函数。不知何故,进度条没有出现,我看到了下一个窗口本身。下面是相同的代码。

from Tkinter import *
import ttk

class App:  
    def __init__(self, master):     
        #copy the root
        self.master = master        

        #Label for the root
        self.title_frame = Frame(self.master)
        self.title_label= Label(self.title_frame, text="My application")

        #position title label
        self.title_frame.pack(fill=X)
        self.title_label.pack() 

        #Create frame containing details
        self.detail_frame1 = Frame(self.master)     
        self.detail_frame2 = Frame(self.master)

        #Create entry for input details
        self.input1 = Entry(self.detail_frame1)

        self.function()

    def function(self):             

        #copy the root window
        master = self.master

        #copy the body frame
        detail_frame = self.detail_frame1

        #position the details frame
        detail_frame.pack()

        #Create the Labels to be displayed in the details frame
        input1_label = Label(detail_frame, text="input:")       

        #button to enter the next window
        next = Button(detail_frame, text="Next", width=26,height=2, command= lambda: self.function1())

        input1_label.grid(row=0, sticky=E, padx=10, pady=10)
        self.input1.grid(row=0, column=2, sticky=W, pady=10)

        next.grid(row=3, column=3, pady=5, padx=5)

    def function1(self):
        pb = ttk.Progressbar(self.detail_frame1, orient='horizontal', mode='indeterminate')
        pb.pack()
        pb.start(1)

        #get the paper code of the paper to be checked
        input1 = self.input1.get()                                      

        # system call based on the value of input1
        call("")
        #

        self.function2()

    def function2(self):
        self.detail_frame1.pack_forget()
        self.detail_frame2.pack()

def main():
#create the root window 
root = Tk()     
root.resizable(width=FALSE, height=FALSE)
app = App(root)
root.mainloop()     

if __name__=='__main__':
    main()

我还尝试在按下下一个按钮时创建一个新窗口,并在该窗口中添加一个进度条。但这也没有用。新窗口一直没有出现,直接转到下一个窗口。

我想看到按钮按下的进度条,直到系统调用被执行并且我们进入下一个窗口。进度条可以在当前窗口或新窗口中。如果它是一个新窗口,当我们进入下一步时应该关闭它。

【问题讨论】:

  • “通话”需要多长时间。然后删除包含进度条“self.detail_frame1.pack_forget()”的框架
  • 我还收到一条错误消息,指出您不能在同一容器的从属服务器上使用网格和打包。你必须自己纠正。至少在测试时,选择包或网格并仅使用它。
  • 对于给定的根,所有小部件都应使用网格或打包。我对根窗口中的所有框架都使用了 pack(),对于给定的框架,我可能使用了网格。如果上述代码中不是这种情况,我很抱歉。 @CurlyJoe
  • call() 实际上是一个在子进程中可用的系统调用。它使用等于 input1 的命令行参数调用单独的 python 脚本。实际上,我试图展示原始代码的简化场景,因此将 call() 留空。因此无法指定执行 call() 可能需要的时间量。 @CurlyJoe

标签: python tkinter call tk


【解决方案1】:

我能够通过多线程“调用”函数来解决我的应用程序中的进度条冻结问题。所以在你的代码中,它看起来像:

import time
import threading
class App:
    def function1(self):
        pb = ttk.Progressbar(self.detail_frame1, orient='horizontal', mode='indeterminate')
    pb.pack()
    pb.start(1)

    #get the paper code of the paper to be checked
    input1 = self.input1.get()

    # system call based on the value of input1
    t = threading.Thread(target=call, args="")
    t.start()

    self.function2()

    def function2(self):
        self.detail_frame1.pack_forget()
        self.detail_frame2.pack()
def call():
    time.sleep(2)

【讨论】:

  • call() 基本上是子进程库中可用的系统调用。因此我们不能像前面提到的那样单独定义 call() 。我使用了这样的调用函数:('C:/Python27/python.exe D:/myApp/externalScript.py --input '+input1+' )。我实际上已经在问题中提到了实际代码的简化版本,因此没有详细说明我如何使用 call()。很抱歉缺少信息。
猜你喜欢
  • 2020-07-10
  • 2020-07-20
  • 2019-11-16
  • 1970-01-01
  • 2014-07-26
  • 2012-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多