2013-09-13 15 views
4

Я пытаюсь написать программу, которая делает список всех .xml-файлов в папке, а затем копирует их в другой каталог и удаляет из исходного каталога. Эта часть программы работает нормально. Я хочу сделать так, чтобы я мог нажать кнопку в графическом интерфейсе, и сканировать и обрабатывать папки, пока я не нажму кнопку, чтобы отключить ее. Опять же, включение его - это не проблема, но попытка остановить это меня сильно озадачила. Я бы хотел, чтобы он подождал некоторое время между ними, но используя time.sleep (x), замораживает всю программу и не позволяет мне вводить больше команд, пока она не перестанет спать, только для того, чтобы она обработалась, а затем снова спала. Любые предложения о том, как по существу запустить/остановить цикл while с помощью кнопки tkinter GUI?Запустить/остановить цикл 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 был найден здесь, и отлично работает, если вам интересно, но я оставил его на место/readibility. Я знаю, что мой код неряшлив, но я только начал программировать.

Любые рекомендации/альтернативные методы приветствуются!

btw: exel - это функция, которую я хочу использовать в цикле!

ответ

2

Основная идея состоит в том, чтобы иметь функцию, которая обрабатывает один файл, а затем вы используете цикл событий для повторного вызова этой функции, пока больше файлов не будет обработано. Вы делаете это с помощью команды 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 мс.

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

+0

Работал отлично после внедрения должным образом! Большое спасибо, что после() хорошо работает как сон, не замораживая GUI. –

Смежные вопросы