【问题标题】:Python Tkinter Spinbox dependenciesPython Tkinter Spinbox 依赖项
【发布时间】:2014-12-04 01:38:39
【问题描述】:

我已经尝试寻找了一段时间,但没有找到,如果之前有人问过这个问题,请原谅我。希望我能很好地解释我想要实现的目标。

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

就目前而言,打开时我有两个 Spinbox 以及我的按钮。第一个 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()

为清晰起见进行了编辑,并将代码变成了一个最小的、完整的、可验证的示例

【问题讨论】:

  • 您能否将其简化为 minimal, complete, verifiable example,我们可以在无需将您的 Y: 驱动器连接到我们的系统的情况下运行它吗?
  • 另外,这里到底出了什么问题?您将用于填充第二个 spinbox 的代码放入第二个 spinbox 的命令而不是第一个的命令中,这似乎很奇怪。是这个问题吗?
  • 或者“层次结构中的第一个文件夹而不是所有文件夹”意味着您希望在第一个旋转框中选择的目录下递归地填充所有文件,而不仅仅是那些直接在那个目录?
  • 你好 abarnert。我正在努力将其简化为最小、完整且可验证的代码。我很抱歉。后者,我需要在第一个 spinbox 中的选定目录下递归地填充第二个 spinbox 中的所有文件,并随着第一个 spinbox 的变化而更新。现在,我只是在第一个 spinbox 的选定目录中获取第一个文件夹。

标签: python user-interface dynamic tkinter dependencies


【解决方案1】:

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


我需要在第二个 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 …],以及 newspin01 周围的 str(…),因为没有理由编写一个收集所有将列表中的元素复制到同一列表的副本中,或者在字符串上调用str


…并随着第一个 spinbox 的变化而更新。

那么你需要在 first 列表框的更改而不是 second 上触发它。

所以,这样做:*

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="",因为后者在技术上是字符串的可迭代,这样使用有点混乱。

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

【讨论】:

  • 嗨,阿巴纳特。我感谢您的帮助。我想我可能误解了一点。我不想要一个完整的递归步行。 os.listdir 给了我我正在寻找的东西,因为我不需要遍历每个子文件夹中的所有子文件夹。我只需要第一组。至于第二个问题,列出的代码仍然只给了我第一个文件夹。我想我可能有点搞砸了我的措辞。我需要根据第一个 spinbox 中的信息动态填充(重新填充?)第二个 spinbox。
  • @Sbenjamin:列出的代码完全符合您的要求。请参阅this pastebin 了解我是如何测试它的。
  • 你说得对,代码确实符合我的要求。我将我所做的与您的粘贴箱进行了比较,然后与我们的讨论进行了比较,我不知道为什么,但我误解了您的意思,尽管它很清楚(我想当我阅读它时是漫长的一天?)但是,我道歉并非常感谢您的时间和帮助。我最终切换到 PyQt 主要是为了更简单的美学目的,并且已经让它一切正常,但这肯定会对我在我的视野中的其他项目有所帮助。我已确保接受您的回答。再次感谢你。 :)
  • @Sbenjamin:可能是个好电话。根据我的经验,PyQt 比 Tkinter 需要更多的前期工作(更难安装,更多的学习曲线,每个 GUI 必须至少设计一点,然后才能将其放入代码中),但对于许多“高级“事情变得更简单,更一致......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-02
  • 2014-12-17
  • 1970-01-01
  • 2013-03-10
  • 2015-09-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多