[英]Start/stop a while loop?
我正在嘗試編寫一個程序,該程序列出一個文件夾中所有.xml文件的列表,然后將它們復制到另一個目錄並從原始目錄中刪除。 該程序的這一部分工作正常。 我要這樣做,以便可以在GUI中單擊一個按鈕,然后掃描並處理文件夾,直到按下按鈕將其關閉為止。 再說一次,打開它不是問題,但是試圖阻止它使我感到困惑。 我希望它在這之間等待一段時間,但是使用time.sleep(x)會凍結整個程序,並且直到停止睡眠后才允許我輸入其他命令,只是讓它處理然后再次進入睡眠狀態。 關於如何從GUI tkinter按鈕開始/停止while循環的任何建議?
代碼如下:
#! python3
import glob
import time
import shutil
import os
import sys
import datetime
import errno
import re
import fnmatch
import tkinter # copy tcl8.5 and tk8.5 to folder
from tkinter import ttk
import sched
flag = 0
with open("config.ini") as f:
g = f.readlines()
sourcedir = g[0][10:-1]
ICdir = g[1][13:-1]
BUdir = g[2][13:-1]
LOGdir = g[3][8:-1]
el = g[4][3:-1]
# reads directories from config.ini
h = len(sourcedir)
# obtains length of address, used later on
def exemel():
m = sorted(glob.glob(sourcedir+"/*.xml"), key=os.path.getmtime)
n = len(m)
if n == 0:
print("none left")
for item in range(n):
try:
m = sorted(glob.glob(sourcedir+"/*.xml"), key=os.path.getmtime)
n = len(m)
if n == 0:
print("none left")
global flag
if flag == 5:
flag = 0
item = item + 1
with FileLock(m[item]):
k = h - len(m[item])
g = m[item][k:]
shutil.copy(m[item], ICdir)
shutil.move(m[item], BUdir)
print(m[item] + " successfully processed.")
dated = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
if os.path.exists(LOGdir):
with open(LOGdir, "a") as logging:
logline = '\n' + '"' + g[1:] + '", #' + dated + "# copied"
logging.write(logline)
else:
with open(LOGdir, "w") as logging:
logline = '"' + g[1:] + '", #' + dated + "# copied"
logging.write(logline)
except PermissionError:
print("File in use, waiting..")
time.sleep(1.5)
flag += 1
continue
except shutil.Error as e:
os.remove(ICdir + g)
os.remove(BUdir + g)
print("Existing files removed..")
dated = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
if el == "1":
if os.path.exists(LOGdir):
with open(LOGdir, "a") as logging:
logline = '\n' + '"' + g[1:] + '", #' + dated + "# overwritten"
logging.write(logline)
else:
with open(LOGdir, "w") as logging:
logline = '"' + g[1:] + '", #' + dated + "# overwritten"
logging.write(logline)
except IndexError:
item = 0
continue
except SystemExit:
break
except KeyboardInterrupt:
break
def prunt():
print("ZES")
def config():
print("config")
def stop():
print("stop")
global x
x = False
global STOP
STOP = True
s = sched.scheduler(time.time, time.sleep)
def run_periodically(start, end, interval, func):
event_time = start
while event_time < end:
s.enterabs(event_time, 0, func, ())
event_time += interval
s.run()
def starter():
run_periodically(time.time(), time.time()+600, 60, exemel)
### GUI BEGIN ###
root = tkinter.Tk()
root.title("XML Wizard")
mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=("N","W", "E", "S"))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)
sourceEntry = ttk.Entry(mainframe, width=50, textvariable=sourcedir)
sourceEntry.grid(column=2, row = 1, columnspan=2)
ttk.Label(mainframe, text="Source Directory:").grid(column=1, row=1, sticky="W")
BackupEntry = ttk.Entry(mainframe, width=50, textvariable=BUdir)
BackupEntry.grid(column=2, row = 2, columnspan=2)
ttk.Label(mainframe, text="Backup Directory:").grid(column=1, row=2, sticky="W")
ImportEntry = ttk.Entry(mainframe, width=50, textvariable=ICdir)
ImportEntry.grid(column=2, row = 3, columnspan=2)
ttk.Label(mainframe, text="Import Directory:").grid(column=1, row=3, sticky="W")
ttk.Button(mainframe, text="Go", command=starter).grid(column=4, row=5, sticky="W")
ttk.Button(mainframe, text="Save Config", command=config).grid(column=5, row=4, sticky="W")
ttk.Button(mainframe, text="Load Config", command=config).grid(column=5, row=3, sticky="W")
ttk.Button(mainframe, text="Stop", command=stop).grid(column=3, row=5, sticky="W")
root.mainloop()
FileLock函數位於此處,如果您想知道,它可以完美運行,但出於空間/可讀性的考慮,我將其省略。 我知道我的代碼草率,但我才剛剛開始編程。
任何建議/替代方法都非常歡迎!
順便說一句:exemel是我要循環的功能!
基本思想是擁有一個處理單個文件的函數,然后使用事件循環重復調用該函數,直到沒有更多文件要處理為止。 您可以使用after
命令執行此操作。
在函數內部,您還可以檢查全局標志。 如果設置了該標志,則該功能不起作用,也不安排任何工作要做。 使用暫停按鈕按鈕設置標志。 設置完畢后,只需調用一次函數,它將繼續運行,直到處理完所有文件。
例如:
def do_one_file():
global files_to_process, paused
if not paused:
file = files_to_process.pop()
... do some work here ...
if len(files_to_process) > 0:
root.after(10, do_one_file)
這將檢查您是否已暫停工作。 如果沒有,它將從文件堆棧中拉出一個文件進行處理。 然后,如果還有更多工作要做,它將安排在10毫秒內處理下一個文件。
假設實際工作僅花費幾百毫秒,您的GUI將保持響應狀態,並且復制在“后台”進行。 我用引號引起來,因為它們全部發生在主線程上,而不是在后台線程或進程上,但是它發生在GUI不執行其他操作的那一刻(實際上是大多數時間)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.