輪詢管我有兩個腳本:Tkinter的應用「凍結」,同時不斷對內容(多)
Processor_child.py:其目的是執行一些數據分析和清理操作。當單獨運行時(不包括Tkinter_parent.py),它必須執行與使用Tkinter_parent.py打包到GUI中時相同的操作。
Tkinter_parent.py:它的目的是爲那些無法直接使用Processor_child的用戶提供GUI。
在Processor_child,有for
循環,即要求用戶輸入的每個迭代。這些提示需要出現在Tkinter應用程序中,接受輸入並將其發送回Processor_child。
下面的代碼這樣做,提高了Entry
字段每當有一個在Pipe
(由環路添加)數據。但是,它似乎經常「凍結」,加載停滯並且沒有通過代碼進行。有時候,它按預期完美運行。 (在這些情況下代碼沒有變化。)
我該如何解決這個問題/使之更穩定?我在下面評論了'凍結'發生的地方。
Tkinter_parent.py:
### Tkinter_parent.py ###
from tkinter import *
from tkinter.filedialog import askopenfilename
from tkinter import ttk
from multiprocessing import Process, Pipe
import pandas as pd
import Processor_child
import time
class GUI:
def __init__(self, master):
self.master = master
def gui_input(message, a_pipe = None):
def input_done(event=None):
entry.pack_forget()
input_label.pack_forget()
submit_button.pack_forget()
a_pipe.send(entry.get())
next_one(a_pipe)
entry = Entry(frame)
input_label = ttk.Label(frame, text=message)
entry.bind("<Return>", input_done)
submit_button = ttk.Button(frame, text="Submit", command=input_done)
input_label.pack()
entry.pack()
submit_button.pack()
def file_select():
dataset_path = askopenfilename()
if __name__ == '__main__':
pipe1, pipe2 = Pipe()
some_vars = ['a var', 'another var']
a_df = pd.read_csv(dataset_path)
p_review = Process(target=Processor_child.review_with_user, args=(some_vars, a_df, pipe2))
p_review.start()
gui_input(pipe1.recv(), pipe1)
#time.sleep(1)
def next_one(pipe1):
while pipe1.poll() != True: ### CAUSES CONSTANT LOADING WITHOUT PROGRESSION
time.sleep(0.1)
gui_input(pipe1.recv(), pipe1)
if __name__ == '__main__':
root = Tk()
my_gui = GUI(root)
root.style = ttk.Style()
root.style.configure('my.TButton')
root.style.configure('my.TLabel')
canvas = Canvas(root)
frame = Frame(canvas)
frame.place()
canvas.pack(side="left", fill="both", expand=True)
canvas.create_window((45,50), window=frame, anchor="nw")
ttk.Button(frame, text="Select", command=file_select).pack()
root.mainloop()
而且processor_child:
### processor_child.py ###
import pandas as pd
from multiprocessing import *
import time
def smart_print(message, a_pipe = None):
if __name__ == "__main__":
print(message)
else:
a_pipe.send(message)
def review_with_user(var_names, dataset, a_pipe = None):
affirmed = []
review_message = 'Yes or no?'
if __name__ == "__main__":
review_response = input(review_message)
else:
smart_print(review_message, a_pipe)
while a_pipe.poll() != True:
time.sleep(0.1)
review_response = a_pipe.recv()
if review_response in ['Yes', 'yes']:
for v in dataset.columns:
smart_print(dataset[v].dropna(), a_pipe)
if __name__ == "__main__":
local_response = input(review_message)
else:
while a_pipe.poll() != True:
time.sleep(0.1)
local_response = a_pipe.recv()
if local_response in ['Yes', 'yes']:
affirmed.append(v)
smart_print(affirmed, a_pipe)
if __name__ == "__main__":
var_names = ['var1', 'var2']
df = pd.read_csv('dummy.csv')
review_with_user(var_names, df)
這涉及到更廣泛的SO質疑How can I implement an input
method in a Tkinter parent script, with the displayed prompt and return value being sent back to a child script?,並且來自一個貼,但無功能,解決方案那裏。
截至2017年10月23日,仍然沒有解決方案。
如果您的目標是通過tkinter GUI與命令行應用程序通信,您可能需要查看我的答案[here](https://stackoverflow.com/questions/21811464/how-can-i-embed -a-蟒-解釋器框架中有蟒-使用-Tkinter的/ 46545426#46545426)。它使用一個子進程,用單獨的線程來獲得輸出。 – Oli
由於gui_input和input_done中的遞歸代碼可能會凍結 –
由於gui_input和input_done中的遞歸代碼,它可能會凍結。而不是next_one(a_pipe),之後使用將安排一個獨立的進程,因此每個函數調用仍在等待從下一個調用返回/退出無限期,即frame.after(100,next_one,a_pipe ) –