当前位置: 首页 > 知识库问答 >
问题:

启动/停止while循环?

时经纬
2023-03-14

我想写一个程序,列出所有的。xml文件,然后将其复制到另一个目录并从原始目录中删除。程序的这一部分运行良好。我想这样做,我可以点击GUI中的一个按钮,让它扫描和处理文件夹,直到我按下一个按钮将其关闭。再说一次,打开它不是问题,但试图阻止它让我难堪。我想在两者之间等待一段时间,但要利用时间。sleep(x)冻结整个程序,在它停止Hibernate之前不允许我输入任何命令,只允许它处理然后再次Hibernate。关于如何从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函数是在这里找到的,如果你想知道,它可以完美地工作,但我把它留在了空间/可读性。我知道我的代码很草率,但我才刚刚开始编程。

欢迎提供任何建议/替代方法!

顺便说一句:样例是我想要循环的函数!

共有1个答案

黄宏大
2023-03-14

基本思想是使用一个处理单个文件的函数,然后使用事件循环反复调用该函数,直到没有更多的文件要处理为止。您可以使用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)

这将检查您是否暂停了工作。如果没有,它将从文件堆栈中提取一个文件来处理和处理它。然后,如果有更多的工作要做,它会安排下一个文件在10ms内处理。

假设实际工作只需要几百毫秒,你的图形用户界面将保持响应,复制发生在“后台”。我把它放在引号中,因为它都发生在主线程上,而不是后台线程或进程上,但是它发生在GUI什么也不做的时候(实际上大部分时间都是这样)。

 类似资料:
  • 有没有你可以开始和停止一个动画,所以播放1秒,停止1秒?我尝试过用单选按钮与Thread.Sleep切换来实现这一点,但是我认为这种方式是不可能的。有没有其他方法可以做到这一点?多谢了。

  • 参考 workerman手册 http://doc3.workerman.net/install/start-and-stop.html

  • 注意Workerman启动停止等命令都是在命令行中完成的。 要启动Workerman,首先需要有一个启动入口文件,里面定义了服务监听的端口及协议。可以参考入门指引--简单开发实例部分 这里以workerman-chat为例,它的启动入口为start.php。 启动 以debug(调试)方式启动 php start.php start 以daemon(守护进程)方式启动 php start.php

  • 不知道如何阻止这个while循环无限重复。我使用检查用户输入是否为int。如果没有输入int值,则循环将无限重复。

  • 我正在开发一个简单的python程序,其中包括创建一个圆圈“按钮”,然后让用户在圆圈内单击。如果他们没有点击圆圈,会出现一条消息,说明他们在圆圈外点击,应该再试一次。然而,在最后一部分,我得到了一个关于代码的无休止的循环,尽管使用了中断。是否有任何人可以帮助查看是否存在错误?谢谢

  • 我有一个文件,我需要读取,打印出整数,捕获异常并继续显示下一个整数,依此类推,直到没有更多的整数。 该文件包含:12 5 sd 67 4 cy 我想让它显示: 12 5 输入错误67 4 输入错误 但是,它只给我12,5,接着输入错误,它就停了。我尝试过将所有内容放入while循环中,但它会无休止地循环,并出现输入异常。 我错过了什么,以便循环继续读取下一个int等等?