Показать индикатор выполнения во время системного вызова в tkinter

Я пытаюсь получить некоторую информацию от пользователя. Я делаю системный вызов и передаю ввод в качестве аргумента при нажатии кнопки (в данном случае «Далее»). За это время я хотел бы добавить неопределенный виджет индикатора выполнения в текущее окно, пока системный вызов не вернет что-то и не попадет в следующую функцию. Почему-то индикаторы выполнения не отображаются, и я вижу следующее окно. Ниже приведен код для того же самого.

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()

Я также попытался создать новое окно при следующем нажатии кнопки и добавить в это окно индикатор выполнения. Но и это не сработало. Новое окно так и не появилось, и меня сразу перевели в следующее окно.

Я хочу видеть индикатор выполнения при нажатии кнопки до тех пор, пока системный вызов не будет выполнен, и мы перейдем к следующему окну. Индикатор выполнения может находиться в текущем окне или в новом окне. Если это новое окно, оно должно быть закрыто, когда мы перейдем к следующему шагу.


person Rahul Patel    schedule 29.06.2015    source источник
comment
Сколько времени занимает звонок. После этого вы удаляете кадр, содержащий индикатор выполнения self.detail_frame1.pack_forget()   -  person    schedule 29.06.2015
comment
Я также получаю сообщение об ошибке, в котором говорится, что вы не можете использовать сетку и упаковку на ведомых устройствах одного и того же контейнера. Вам придется исправить это самостоятельно. По крайней мере, при тестировании выберите пакет или сетку и используйте только их.   -  person    schedule 29.06.2015
comment
Для данного корня все виджеты должны либо использовать сетку, либо пакет. Я использовал pack() для всех кадров в корневом окне, а для данного кадра я мог бы использовать сетку. Извините, если это не так в приведенном выше коде. @Кудрявый Джо   -  person Rahul Patel    schedule 29.06.2015
comment
call() на самом деле является системным вызовом, который доступен в подпроцессе. Он вызывает отдельный скрипт Python с аргументом командной строки, равным input1. На самом деле я попытался продемонстрировать упрощенный сценарий исходного кода, поэтому просто оставил call() пустым. Следовательно, нельзя указать количество времени, которое может потребоваться для выполнения call(). @Кудрявый Джо   -  person Rahul Patel    schedule 29.06.2015


Ответы (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)
person David Gonzalez    schedule 29.06.2015
comment
call() — это в основном системный вызов, доступный в библиотеке подпроцессов. Следовательно, мы не можем определить call() отдельно, как уже упоминалось. Я использовал функцию вызова следующим образом: ('C:/Python27/python.exe D:/myApp/externalScript.py --input '+input1+'). На самом деле я упомянул упрощенную версию фактического кода в вопросе и, следовательно, не подробно описал, как именно я использую call(). Извините за недостающую информацию. - person Rahul Patel; 29.06.2015