我在 Tkinter 中的 root.after 函式有問題。
我正在嘗試運行一個子行程,當它運行時,我檢查 process.poll(),如果它仍然為 None,則回呼檢查函式:
self.PingProcess = subprocess.Popen(
r'powershell.exe -ExecutionPolicy RemoteSigned -file "file1.ps1"',
stdout=sys.stdout)
self.PingContinuous() # Checks the PingProcess poll until the process is finished
AceThread = threading.Thread(target=self.CheckAce())
AceThread.start()
DrivesThread = threading.Thread(target=self.CheckDrives())
DrivesThread.start()
self.continuous_check() # Checks the AceThread and DrivesThread (there are
# processes in them)
def PingContinuous(self):
PingProcess = self.PingProcess.poll()
if PingProcess is None:
self.ui.root.after(500, self.PingContinuous)
else:
print("Finished")
def CheckAce(self):
self.AceProcess = subprocess.Popen(
r'powershell.exe -ExecutionPolicy RemoteSigned -file "file.ps1"',
stdout=sys.stdout)
def CheckDrives(self):
self.DrivesProcess = subprocess.Popen(
r'powershell.exe -ExecutionPolicy RemoteSigned -file "file3.ps1"',
stdout=sys.stdout)
def continuous_check(self):
AceProcess = self.AceProcess.poll()
DrivesProcess = self.DrivesProcess.poll()
if PingProcess is None and DrivesProcess is None:
self.ui.root.after(500, self.continuous_check)
else:
print("Finished Ace and Drives")
問題是PingContinuous()應該繼續與
self.ui.root.after(500, self.PingContinuous)
但相反,它只是跳回到:
AceThread = threading.Thread(target=self.CheckAce())
AceThread.start()
DrivesThread = threading.Thread(target=self.CheckDrives())
DrivesThread.start()
self.continuous_check() # Checks the AceThread and DrivesThread (there are
# processes in them)
并開始跳之間來回self.continuous_check和self.PingContinuous。
我需要的是PingProcess完成,然后運行其余的執行緒。
我不能使用 time.sleep 或 process.wait(),因為這會凍結我的 GUI
uj5u.com熱心網友回復:
PingContinuous沒有阻塞。您正在呼叫它(這可能是有效的),它會在新執行緒中設定對自身的呼叫以備后用,然后繼續進行處理AceThread。
您可以PingContinuous在回圈中運行一個新執行緒而不是遞回,然后join在繼續之前讓您的主執行緒成為新執行緒(這樣它會阻塞直到 PingContinuous 完成)?像這樣的東西:
def PingContinuous(self):
while not self.PingProcess.poll():
# You might want a maximum number of iterations before giving up, too
# so that you don't loop forever if it's broken
time.sleep(500)
print("Finished")
pingThread = threading.Thread(target=self.PingContinuous)
pingThread.start()
pingThread.join()
# Now carry on with AceThread etc. here
...但這也可能會阻止您的 GUI,具體取決于您的運行方式。您可能需要將 GUI 和程式邏輯置于不同的執行緒中,以便您可以阻塞一個而不阻塞另一個。
uj5u.com熱心網友回復:
.after()在您的代碼中的使用作業正常。
實際上你不需要運行self.CheckAce()和self.CheckDrives()使用執行緒:
...
self.CheckAce()
self.CheckDrives()
self.continuous_check()
...
里面也有錯別字continuous_check():PingProcess應該是AceProcess。
def continuous_check(self):
AceProcess = self.AceProcess.poll()
DrivesProcess = self.DrivesProcess.poll()
# Typo: PingProcess should be AceProcess instead
if AceProcess is None and DrivesProcess is None:
self.ui.root.after(500, self.continuous_check)
else:
print("Finished Ace and Drives")
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/367122.html
標籤:Python 用户界面 特金特 python-多线程 传统知识
