python-3.x - 如何在 tkinter 中重现课程
问题描述
我使用 tkinter 构建了一个小的 Synchronizer GUI 程序。我最近尝试添加一个 +-Button,它再现了文件浏览按钮和输入字段,因此我可以同步 2 个以上的目录。(即我个人将我的文档和图片备份在我想要保持更新的 USB 驱动器上,但我不想复制我的整个 /home 目录。)
我遇到了两个问题。第一个问题是加号按钮的定位:我已将行数初始化为零,因此每次单击 + 按钮时,按钮/字段的新行实际上是在新行上。可悲的是,这不适用于在函数之外定义的加号按钮,但 self.rowcount += 1 不应该为整个班级调整行数吗?self.sourcefile
其次,我不确定如何处理self.targetfile
:当我选择一个新文件夹时,它会替换以前的输入,这不是想法。
我真的很感激任何帮助!
from tkinter import *
from tkinter import filedialog
class Application():
def __init__(self):
self.root = Tk()
self.rowcount = 0
self.sourcefile = ""
self.targetfile = ""
self.sourceDirectory = Entry(self.root, width=10)
self.targetDirectory = Entry(self.root, width=10)
self.sourceDirectory.insert(0, "Source")
self.targetDirectory.insert(1, "Target")
selectSource = Button(self.root, text = "browse source", command=self.select_source, height=15, width=15)
selectTarget = Button(self.root, text = "browse target", command=self.select_target, height=15, width=15)
plusButton = Button(self.root, text = "+", command=self.create_new)
self.sourceDirectory.grid(row=0, column=0)
self.targetDirectory.grid(row=0, column=5)
selectSource.grid(row=0, column=1)
selectTarget.grid(row=0, column=10)
plusButton.grid(row=self.rowcount + 1, column=10)
self.root.mainloop()
def create_new(self):
self.rowcount += 1
print(self.rowcount)
self.sourceDirectory = Entry(self.root, width=10)
self.targetDirectory = Entry(self.root, width=10)
self.sourceDirectory.insert(0, "Source")
self.targetDirectory.insert(1, "Target")
selectSource = Button(self.root, image=self.browsericon, command=self.select_source, height=15, width=15)
selectTarget = Button(self.root, image=self.browsericon, command=self.select_target, height=15, width=15)
self.sourceDirectory.grid(row=self.rowcount, column=0)
self.targetDirectory.grid(row=self.rowcount, column=5)
selectSource.grid(row=self.rowcount, column=1)
selectTarget.grid(row=self.rowcount, column=10)
def select_source(self):
source = filedialog.askdirectory(title="Select Source")
self.sourceDirectory.delete(0, END)
self.sourceDirectory.insert(0, source)
self.sourcefile = source
def select_target(self):
target = filedialog.askdirectory(title="Select Target")
self.targetDirectory.delete(0, END)
self.targetDirectory.insert(1, target)
self.targetfile = target
Application()
解决方案
self.rowcount += 1 不应该为全班调整行数吗?
是的,它在你的代码中。但是,更改变量不会更改在grid
命令中使用该变量的小部件的位置。
我的建议是将行放在一个框架中,将按钮放在另一个框架中。这样您就不必不断调整按钮的位置。例如:
self.row_frame = Frame(self.root)
self.button_frame = Frame(self.root)
self.button_frame.pack(side="bottom", fill="x")
self.row_frame.pack(side="top", fill="both", expand=True
此外,如果“+”按钮创建了一个新行,它不应该是重复代码。您需要一个用于添加行的函数。由于您已经有一个函数来执行此操作,因此您可以在__init__
.
把它们放在一起看起来像这样:
class Application():
def __init__(self):
self.root = Tk()
self.root.title("File Synchronizer")
self.rowcount = 0
self.sourcefile = ""
self.targetfile = ""
self.row_frame = Frame(self.root)
self.button_frame = Frame(self.root)
self.button_frame.pack(side="bottom", fill="x")
self.row_frame.pack(side="top", fill="both", expand=True)
startSync = Button(self.button_frame, text="Start", command=self.synchronize)
plusButton = Button(self.button_frame, text = "+", command=self.create_new)
startSync.grid(row=1, column=2)
plusButton.grid(row=0, column=10)
self.create_new()
self.root.mainloop()
def create_new(self):
self.rowcount += 1
self.sourceDirectory = Entry(self.row_frame, width=10)
self.targetDirectory = Entry(self.row_frame, width=10)
self.sourceDirectory.insert(0, "Source")
self.targetDirectory.insert(1, "Target")
selectSource = Button(self.row_frame, text = "browse source", command=self.select_source)
selectTarget = Button(self.row_frame, text = "browse source", command=self.select_target)
self.sourceDirectory.grid(row=self.rowcount, column=0)
self.targetDirectory.grid(row=self.rowcount, column=5)
selectSource.grid(row=self.rowcount, column=1)
selectTarget.grid(row=self.rowcount, column=10)
这并没有将“加号”和“开始”按钮放在完全相同的位置,但这只是因为它与答案有些无关。您可以使用任何您想将其放置在按钮框架中的选项。由于两个框架是独立的,您可以在一个框架中调整行、列和权重,而不会影响另一个框架。或者,您可以pack
在一个框架和grid
另一个框架中使用。
您的代码的另一个问题是它self.sourceDirectory
只能self.targetDirectory
保存一个值,因此它将始终引用最后创建的小部件。
由于您正在创建多个源和目标小部件,因此您需要将它们保存在一个列表中。
例如,首先在__init__
方法中向您的应用程序添加一个空列表:
self.sources = []
self.targets = []
然后,当您添加新行时,将其附加到列表中:
source_entry = Entry(self.row_frame, width=10)
target_entry = Entry(self.row_frame, width=10)
self.sources.append(source_entry)
self.targets.append(target_entry)
然后,您可以遍历这两个列表以处理所有源值和目标值。
您还必须修改浏览函数的回调以接受索引,以便按钮知道要更新哪个条目。
推荐阅读
- javascript - JavaScript | 如果再次调用函数,则重新启动计时器
- amazon-dynamodb - 无服务器定义具有 GlobalSecondaryIndexes 的 Dynamodb
- c++ - 禁止特定的消毒剂检查,但在所有其他程序上仍然失败
- google-cloud-dataflow - PubsubIO 需要哪些 GCP 权限
- java - 为什么我收到错误:流已关闭
- python - Python 文本冒险 销售,检查是否在列表中
- node.js - Discord.js 机器人命令错误:警告命令
- azure - 将 Azure 资源日志路由到多个 Log Analytics 工作区
- javascript - 我想在javascript中选中复选框时对数字求和
- arrays - 如何使用 SwiftyJSON 将数组转换为字典?