如何正确地集成tkinter.Tk.mainloop并循环遍历python中的迭代器?

时间:2017-12-28 08:17:10

标签: python tkinter iterator

我正在开发一个简单的应用程序来帮助我快速查看并将大量图像分类到两个类别(审查和清理ML任务的数据集)。

这次我决定试试tkinter,因为我之前没有任何经验。

我现在所拥有的内容如下所示:python + pseudocode

import os
import shutil
import tkinter
from scandir import scandir

class MainWindow(object):
    def __init__(self, data_root):
        self.data_root = data_root
        self.scanned = scandir(self.data_root)
        self.entry = None

        self.create_dirs(['catA', 'catB'])

        # set up main window
        self.root = tkinter.Tk()
        self.image = tkinter.Frame( .... )
        self.canvas = tkinter.Canvas(self.image, ...)

        self.b_catA = tkinter.Button(self.root, text='category A')
        self.b_catA.bind("<Button-1>", self.on_catA_callback)

        self.b_catB = tkinter.Button(self.root, text='category B')
        self.b_catB.bind("<Button-1>", self.on_catB_callback)

        # other setup, packing of widgets, etc

     def display(self):
         self.load_image(self.entry.path)
         self.root.update()

     def run(self):
         self.next_file()
         self.root.mainloop()

 # I particularly don't like three methods below, 
 # especially explicit call to __next__() in next_file()

     def next_file(self):
         while True:
             self.entry = self.scanned.__next__()
             if self.entry.is_file():
                 self.display()
                 return

     def on_catA_callback(self, event):
         print("Move {src} -> {dst}".format(src=self.entry.path, dst=self.catA_path))
         shutil.move(self.entry.path, self.cat_A_path)
         self.next_file()

     def on_catB_callback(self, event):
         print("Move {src} -> {dst}".format(src=self.entry.path, dst=self.catB_path))
         shutil.move(self.entry.path, self.catB_path)
         self.next_file()

if __name__ == '__main__':
    scn = MainWindow('/path/to/data')
    scn.run()

尝试在下面的伪代码中描述我的目标

for entry in scandir(data_root):
    load_and_display_image_from(entry.path)
    wait_for_user_to_press_a_button()
    process_button_press()

我不喜欢这个简单的循环分布在3个函数上:next_file和两个按钮回调。如果我添加更多按钮,这种传播会变得更大。

这是另一个问题:我的应用程序的生命周期由data_root中存在的文件控制。我希望在处理完所有文件时关闭主窗口。

是否可以将scandir迭代器放在一个位置?

据我所知,我必须写一个Tk.mainloop()的替代品,然而,我无法弄清楚,怎么做。

此功能有一个参数。我认为这是一些迭代,但看起来不是。当我提供一些值时,窗口会显示并关闭,而不会等待按下按钮。

更新 尝试使用next_file

重写yield
def next_file(self):
    for self.entry in scandir(self.data_root):
        if self.entry.is_file():
            self.display()
            yield
    self.root.quit()

现在我看不到图像,只看到按钮。还尝试在调用self.display()时设置断点 - 此断点永远不会被命中。

0 个答案:

没有答案