关于你的代码有很多事情需要考虑,我将一一解决。
- 您正在导入所有
tkinter,没有任何别名
- 调用你的
root“doc1”意味着你认为你会在那个类之外制作一个“doc2”、“doc3”等,这是行不通的。您不能有很多 root 实例。充其量应该是Toplevel,但前提是您打算为每个新文档打开一个新窗口。
- 你根本不应该在课堂上调用
mainloop。您应该使用模块约定。这样,您可以将该脚本的元素导入另一个脚本,而不必担心该脚本会自动运行。至少,为mainloop 创建一个包装器是愚蠢的。您已经可以调用mainloop,将其粘贴在另一个方法中的目的是什么? (doc1.root.mainloop())
- 创建一个方法来进行非常具体的网格放置是不可重复使用的。我认为
mixin 使某些功能更可用,但保持它们动态将是更好的方法。没有必要为小部件创建自定义包装器,但是如果您要在所有内容上放置 gridding 方法,那么为什么不制作更好的 gridding 方法并将其自动“混合”到适用的所有内容中呢?只要您能做到这一点,您还可以加入一些其他便利。
-
Document 之类的东西(即,您可能需要很多或可能经常更改的东西)可能不应该是root。它应该在root 中。它当然不应该将root 作为属性埋在其中。
下面给出了我上面所说的许多例子。这些例子可以而且应该被修饰。例如,BaseWidget 可以包含x、rootx、y、rooty 等的属性... ParentWidget 的设计方式,您可以使用range 作为@ 的第一个参数987654343@ 和 colcfg 在一次通话中进行“批量配置”。它们都返回self,所以它们可以内联使用。
import tkinter as tk
from typing import Iterable
class BaseWidget:
@property
def width(self) -> int:
self.update_idletasks()
return self.winfo_width()
@property
def height(self) -> int:
self.update_idletasks()
return self.winfo_height()
def grid_(self, r=None, c=None, rs=1, cs=1, s='nswe', **kwargs):
#this allows keyword shorthand, as well as original keywords
#while also allowing you to rearrange the above arguments
#so you know the exact order they appear and don't have to use the keyword, at all
self.grid(**{'row':r, 'column':c, 'rowspan':rs, 'columnspan':cs, 'sticky':s, **kwargs})
#return self so this can be used inline
return self
class ParentWidget:
@property
def descendants(self):
return self.winfo_children()
#inline and ranged grid_rowconfigure
def rowcfg(self, index, **options):
index = index if isinstance(index, Iterable) else [index]
for i in index:
self.grid_rowconfigure(i, **options)
#so this can be used inline
return self
#inline and ranged grid_columnconfigure
def colcfg(self, index, **options):
index = index if isinstance(index, Iterable) else [index]
for i in index:
self.grid_columnconfigure(i, **options)
#so this can be used inline
return self
class Custom_Label(tk.Label, BaseWidget):
@property
def text(self) -> str:
return self['text']
@text.setter
def text(self, value:str):
self['text'] = value
def __init__(self, master, **kwargs):
tk.Label.__init__(self, master, **kwargs)
class Document(tk.Frame, ParentWidget, BaseWidget):
def __init__(self, master, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
#the rest of this class is an example based on what little code you posted
#the results are not meant to be ideal. It's a demo of usage ... a gist
self.file_name = Custom_Label(self, text='File Name').grid_(1,2)
self.doc_title = Custom_Label(self, text='Document Title').grid_(2,2)
#possible
#r = range(len(self.descendants))
#self.colcfg(r, weight=1).rowcfg(r, weight=1)
self.colcfg(2, weight=1).rowcfg([1,2], weight=1)
class Root(tk.Tk, ParentWidget):
def __init__(self, title, width, height, x, y, **kwargs):
tk.Tk.__init__(self)
self.configure(**kwargs)
self.title(title)
self.geometry(f'{width}x{height}+{x}+{y}')
self.rowcfg(0, weight=1).colcfg(0, weight=1)
doc1 = Document(self).grid_()
if __name__ == '__main__':
Root('MyApplication', 800, 600, 200, 200, bg='#000000').mainloop()