【问题标题】:Troubleshooting frame expansion with tkinter使用 tkinter 对帧扩展进行故障排除
【发布时间】:2019-01-02 15:47:09
【问题描述】:

我的目标是让我的新的自定义 GUI 应用程序(它是 tkinter.Frame 的子类)在调整其父窗口大小时在两个方向上独立展开。当我第一次使用原生 tkinter 类在脚本中构建它时,这很有效(请参阅帖子底部的代码),但自从我将它重组为子类(请参阅下面的第一个代码块)后,它坚持保留它的调整大小时的原始比例。也就是说,如果我最大化父窗口,主 GUI 框架只会沿对角线展开,直到它到达屏幕底部。然后右侧窗口的其余部分将保留为空白的灰色空间。

我的问题是:我在导致此问题的类实现中做错了什么?

Here is a screenshot 的问题,下面是用于生成图片中的 GUI 的代码(请原谅丑陋的配色方案,它只是为了在设计/调试时帮助我的框架保持笔直):

[编辑删除不必要的代码(在这部分中,生成我看到的帧所需的代码比最初想象的要多,所以我不能剪那么多):]

from tkinter import *
from tkinter import ttk

class CharDbGui(Frame):
    # Mage character database object
    def __init__(self, root, database=None, *args, **kwargs):
        Frame.__init__(self, root, *args, **kwargs)
        self.root = root

        ### Broad layout into color-coded frames first ###
        self.rowweight(range(1, 5), [10, 40, 40, 10])
        self.colweight(range(1, 4), [25, 75, 25])
        top_toolbar = Frame(self, bg="green", height=50, width=1)
        top_toolbar.grid(row=1, column=1, columnspan=4, sticky=E+W+N+S)
        leftbox = Frame(self, height=1, width=1)
        leftbox.grid(row=2, column=1, rowspan=2, sticky=N+S+E+W)
        midbox = Frame(self, bg="white", height=1, width=1)
        midbox.grid(row=2, column=2, rowspan=2, sticky=N+S+E+W)
        righttopbox = Frame(self, bg="black", height=1, width=1)
        righttopbox.grid(row=2, column=3, sticky=N+S+E+W)
        rightbottombox = Frame(self, bg="purple", height=1, width=1)
        rightbottombox.grid(row=3, column=3, sticky=N+S+E+W)
        bottombox = Frame(self, bg="orange", height=1, width=1)
        bottombox.grid(row=4, column=1, columnspan=4, sticky=N+S+E+W)
        entity_type_list = ttk.Treeview(leftbox)
        entity_type_list.pack(expand=True, side=LEFT, fill=BOTH)
        sb_etl = Scrollbar(leftbox)
        sb_etl.pack(side=LEFT, fill=Y)

        ### Placeholder widgets ###
        mainbox = Text(midbox, bg="white")
        mainbox.pack(expand=True, fill=BOTH)
        reserved = Text(rightbottombox, bg="purple", width=1)
        reserved.pack(expand=True, fill=BOTH)
        logbox = Text(bottombox, height=6, width=80, bg="orange")
        logbox.pack(expand=True, fill=BOTH)

        ### Create buttons at upper half of right edge ###
        # Create frame to contain the buttons
        bwidth = 12  # button width
        b1 = Button(righttopbox, text="New", width=12)
        b1.grid(row=1, column=1, sticky="")
        b2 = Button(righttopbox, text="Edit", width=12)
        b2.grid(row=2, column=1, sticky="")
        b3 = Button(righttopbox, text="Organize", width=12)
        b3.grid(row=3, column=1, sticky="")
        b4 = Button(righttopbox, text="Templates", width=12)
        b4.grid(row=4, column=1, sticky="")
        b5 = Button(righttopbox, text="Delete", width=12)
        b5.grid(row=5, column=1, sticky="")

        # Space buttons vertically
        righttopbox.grid_rowconfigure(1, weight=1)
        righttopbox.grid_rowconfigure(2, weight=1)
        righttopbox.grid_rowconfigure(3, weight=1)
        righttopbox.grid_rowconfigure(4, weight=1)
        righttopbox.grid_rowconfigure(5, weight=1)

        # add self to root
        self.pack(expand=True, fill=BOTH)

    def rowweight(self, index, weight):
        # Adjust weight(s) of row(s).
        if type(index) == int:  # Singleton case
            assert(type(weight) == int)
            self.root.grid_rowconfigure(index, weight=weight)
        else:  # Range case
            assert(len(index) == len(weight))
            for i, w in zip(index, weight):
                self.root.grid_rowconfigure(i, weight=w)

    def colweight(self, index, weight):
        # Adjust weight(s) of column(s).
        if type(index) == int:  # Singleton case
            assert(type(weight) == int)
            self.root.grid_columnconfigure(index, weight=weight)
        else:  # Range case
            assert(len(index) == len(weight))
            for i, w in zip(index, weight):
                self.root.grid_columnconfigure(i, weight=w)

    def fillDefaults(self):
        # Placeholder values to test with
        self.root.title("Test Database")
        # Populate the list with some initial values
        initvals_etl = ["Characters", "Items"]
        for x in initvals_etl:
            self.tree.insert('', END, x, text=str(x))

        y = self.tree.insert('', END, "nums", text="Numbers")
        for x in range(100):
            self.tree.insert(y, END, x, text=str(x))

    def launch(self):
        self.root.mainloop()


if __name__ == '__main__':
    root = Tk()
    gui = CharDbGui(root)
    root.wm_state('zoomed')
    gui.launch()

然后here is a picture想要它的样子,下面是用于生成它的非类代码:

[编辑删除不必要的代码:]

from tkinter import *
from tkinter import ttk

### FUNCTION DEFINITIONS ###
def rowweight(index, weight):
    # Adjust weight(s) of row(s).
    if type(index) == int:  # Singleton case
        assert(type(weight) == int)
        master.grid_rowconfigure(index, weight=weight)
    else:  # Range case
        assert(len(index) == len(weight))
        for i, w in zip(index, weight):
            master.grid_rowconfigure(i, weight=w)


def colweight(index, weight):
    # Adjust weight(s) of column(s).
    if type(index) == int:  # Singleton case
        assert(type(weight) == int)
        master.grid_columnconfigure(index, weight=weight)
    else:  # Range case
        assert(len(index) == len(weight))
        for i, w in zip(index, weight):
            master.grid_columnconfigure(i, weight=w)


### BUILDING THE GUI LAYOUT AND WIDGETS ###
# Create window that frames all our pieces
master = Tk()
master.title("Test Database")

### Broad layout into frames first ###
rowweight(range(1, 5), [10, 40, 40, 10])
colweight(range(1, 4), [25, 75, 25])
top_toolbar = Frame(master, bg="green", height=50, width=1)
top_toolbar.grid(row=1, column=1, columnspan=4, sticky=E+W+N+S)
leftbox = Frame(master, height=1, width=1)
leftbox.grid(row=2, column=1, rowspan=2, sticky=N+S+E+W)
midbox = Frame(master, bg="white", height=1, width=1)
midbox.grid(row=2, column=2, rowspan=2, sticky=N+S+E+W)
righttopbox = Frame(master, bg="black", height=1, width=1)
righttopbox.grid(row=2, column=3, sticky=N+S+E+W)
rightbottombox = Frame(master, bg="purple", height=1, width=1)
rightbottombox.grid(row=3, column=3, sticky=N+S+E+W)
bottombox = Frame(master, bg="orange", height=1, width=1)
bottombox.grid(row=4, column=1, columnspan=4, sticky=N+S+E+W)

master.mainloop()

【问题讨论】:

  • 您为根设置了权重,但您需要为框架设置它。将self.root.grid_columnconfigure(index, weight=weight) 更改为self.grid_columnconfigure(index, weight=weight),行也一样。
  • 一共4个地方需要去掉root属性。
  • 如果您尝试解决“框架扩展”问题,我建议您删除尽可能多的小部件。就目前而言,您发布了太多不相关的代码。
  • class CharDbGui() 中添加这一行self.columnconfigure(2, weight=1)self.rowconfigure(3, weight=1)。这应该可以解决您的调整大小问题。
  • 啊,很好,小说,谢谢。返回并添加“根”内容时意外过度使用它。我为所有不相关的代码道歉;我是新来的,Python 的新手,因为我无法发现问题,所以我不确定什么是相关的。将来我会尽力做得更好,我会回过头来编辑这篇文章,只包含相关部分,因为我知道它们是什么。再次感谢您为我发现了这一点。

标签: python user-interface tkinter expand subclassing


【解决方案1】:

小说在cmets中给出了这个问题的正确答案:

您为根设置了权重,但您需要为框架设置它。 将 self.root.grid_columnconfigure(index, weight=weight) 更改为 self.grid_columnconfigure(index, weight=weight),对于 行。

我在设计课程时回过头来添加“root”,直到评论中指出时我才注意到我这样做了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-19
    • 1970-01-01
    • 2020-10-02
    • 2011-02-07
    • 2013-11-20
    • 1970-01-01
    相关资源
    最近更新 更多