Python Tkinter Spinbox依赖项

时间:2014-12-02 23:08:53

标签: python user-interface dynamic tkinter dependencies

我已经尝试过寻找一段时间,但是空了,所以请原谅我,如果以前曾经问过这个问题。希望我能够很好地解释我想要实现的目标。

我正在尝试为我的工作室创建一个简单的资产管理GUI,并且在使用Tkinter的Spinbox时遇到了一些麻烦,特别是与它有依赖关系。我们有一个特定的文件结构(用于测试目的是大约4个文件夹深),用于组织各种资产。我对整个Tkinter有点新意,但我已经创建了足够好的GUI,我现在相信它是为了测试目的(请指导我纠正你可能看到的任何错误。)

就目前而言,在开放时我有两个Spinboxes以及我的按钮。第一个Spinbox按预期执行,但是当我试图让第二个Spinbox显示第一个Spinbox中选择的值时,我遇到了麻烦。第二个Spinbox只想显示层次结构中的第一个文件夹,而不是显示该目录中的所有文件夹(也不是它们后续的子文件夹)。如何让第二个Spinbox显示其他文件夹并更新为第一个Spinbox更改?我基本上需要它来动态填充和重新填充第一个旋转框中的选项更改。我在下面粘贴了我的代码。任何帮助都会非常感激。 :)

import os
import Tkinter as tk

mainpath = "C:\\"

def mywindow():
    top = tk.Tk()
    top.wm_title("Muse Asset Manager v01.00")
    top.geometry("+825+500")
    frame = tk.Frame(top)

    spin01 = tk.Spinbox(frame, values = ([i for i in os.listdir(mainpath)]), wrap = True, state = "readonly")

    def secondspincommand():
        newspin01 = spin01.get()
        myspin = [i for i in os.listdir(mainpath + str(newspin01))]
        print myspin
        spin02.config(values = myspin)
    spin02 = tk.Spinbox(frame, values = "", wrap = True, state = 'readonly', command = secondspincommand)

    b1 = tk.Button(frame, text = "Import")
    def button01():
        print secondpath
        top.destroy()
        return
    b1.configure(command = button01)

    spin01.grid(row=1)
    spin02.grid(row=2)
    b1.grid(row=3)
    frame.pack()
    frame.mainloop()
mywindow()

编辑清晰,并将代码转换为最小,完整,可验证的示例

1 个答案:

答案 0 :(得分:0)

好的,这里有两个不同的问题。


  

我需要第二个spinbox在第一个spinbox中的所选目录下以递归方式填充所有文件......

您正在致电listdir。它只是直接列出给定目录下的文件,与Windows命令行中的dir命令相同。

如果你想在它下面获取递归的所有文件,你需要一个递归列出所有这些文件的函数。这是os.walk的用途。

当然walk并不像listdir那么简单,但那是因为它更灵活。如果您想要的只是常规文件(不是路上的子目录),以及每个文件的完整路径,那么应该这样做:*

myspin = [os.path.join(root, file)
          for root, dirs, files in os.walk(mainpath + newspin01)
          for file in files]

*请注意,我已经摆脱了整个事物外围的额外[i for i in …]以及str(…)周围的newspin01,因为没有理由写一个列表理解,将列表中的所有元素收集到同一列表的副本中,或者在字符串上调用str


  

...并在第一个旋转框更改时更新。

然后你需要触发第一个列表框的更改,而不是第二个

所以,这样做:*

def firstspincommand():
    # the code you used to have as secondspincommand

spin01 = tk.Spinbox(frame, values=([i for i in os.listdir(mainpath)]), 
                    wrap=True, state="readonly", command=firstspincommand)
spin02 = tk.Spinbox(frame, values=[""], 
                    wrap=True, state='readonly')

*我还更改了一些符合PEP8标准的内容,并且在合理大小的屏幕上可读,我使用了values=[""]代替values="",因为后者在技术上是一个可迭代的字符串,以这种方式使用它有点令人困惑。

当然,您可能希望某些其他代码在更改第二个框的选项时运行,但显然不是填充第二个框的代码。