Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 更改Tkinter中帧的制表符顺序 总结_Python_Python 3.x_Tkinter - Fatal编程技术网

Python 更改Tkinter中帧的制表符顺序 总结

Python 更改Tkinter中帧的制表符顺序 总结,python,python-3.x,tkinter,Python,Python 3.x,Tkinter,如何将一个框架中包含的tab order窗口小部件提升到另一个框架中包含的窗口小部件(首先创建)之上 完整版本 我有一个Tkinter表单,我将多个小部件分组到框架中,然后使用网格布局将框架定位到窗口中。在我的特定用例中,框架是从ttk.Frame派生的类,但这对这个问题没有任何影响,因为就这个问题而言,它对表单行为没有影响 对于我的用例,在一个循环中创建多个帧是有意义的,以避免代码重复。正如预期的那样,小部件的选项卡顺序是创建它们的顺序。但是,在本例中,表单的自然流程是按以下顺序在小部件之间进

如何将一个框架中包含的tab order窗口小部件提升到另一个框架中包含的窗口小部件(首先创建)之上

完整版本 我有一个Tkinter表单,我将多个小部件分组到框架中,然后使用网格布局将框架定位到窗口中。在我的特定用例中,框架是从
ttk.Frame
派生的类,但这对这个问题没有任何影响,因为就这个问题而言,它对表单行为没有影响

对于我的用例,在一个循环中创建多个帧是有意义的,以避免代码重复。正如预期的那样,小部件的选项卡顺序是创建它们的顺序。但是,在本例中,表单的自然流程是按以下顺序在小部件之间进行制表:
[0、1、2、3、4、10、11、12、5、6、7、8、9]
(请参见下文)

在包含小部件10-12的框架上执行
提升
,不会更改选项卡顺序。但是,在小部件10-12上单独提升会产生以下异常:

_tkinter.TclError: can't raise ".tabtest.frame_2.widget_10" above ".tabtest.frame_1.widget_5
这应该是可行的,但如何做到呢

编辑 正如评论(如下)所述,乍一看,这似乎是问题的重复。在提交我的问题之前,我审查了这个问题。然而,这个问题的答案特别提到在单个框架内为小部件设置选项卡顺序。当我运行答案中包含的示例时,它的效果与预期一样。但是,将其应用于我的用例时:

  • 尝试提升框架不会导致选项卡行为发生变化

  • 尝试提升框架中包含的各个小部件会产生上述错误

MCVE 使用Python 3.4编写

import tkinter as tk
from tkinter import ttk

class TabTest(ttk.Frame):
    def __init__(self, master, *args, **kwargs):
        super().__init__(master, *args, **kwargs)

        # Remove row/column weights.
        for i in range(50):
            self.rowconfigure(i, weight=0)
            self.columnconfigure(i, weight=0)

        # Entry fields.
        frames = []
        entries = []

        x = 0
        for i in range(2):
            f = ttk.Frame(self, takefocus=0, name='frame_{}'.format(i))
            for j in range(5):
                e = ttk.Entry(f, name='widget_{}'.format(x))
                entries.append(e)
                e.insert(tk.END, 'Widget {}'.format(x))
                e.pack(side='top', anchor='w')
                x += 1

            frames.append(f)

        # Buttons
        buttons = []
        f = ttk.Frame(self, takefocus=0, name='frame_2')
        for i in range(3):
            b = ttk.Button(f, text='Widget {}'.format(x),
                           name='widget_{}'.format(x))  
            buttons.append(b)
            b.pack(fill='x')
            x += 1

        frames.append(f)

        frames[0].grid(row=0, column=0, rowspan=5, columnspan=2,
                       padx=2, pady=2, sticky='news')
        frames[2].grid(row=0, column=2, rowspan=5, columnspan=2,
                       padx=2, pady=2, sticky='news')
        frames[1].grid(row=0, column=4, rowspan=5, columnspan=2,
                       padx=2, pady=2, sticky='news')

        frames[2].lift()  # No difference in tab order.
#         for btn in buttons:
#             btn.lift(entries[5])  # Generates exception: _tkinter.TclError: can't raise ".tabtest.frame_2.widget_10" above ".tabtest.frame_1.widget_5

        self.buttons = buttons
        self.frames = frames
        self.entries = entries

        self.pack(fill='both')
        root = self._root()
        root.update()
        root.minsize(root.winfo_width(), root.winfo_height())



def main():
    root = tk.Tk()
    app = TabTest(root, name='tabtest')
    root.mainloop()



if __name__ == '__main__':
    main()

您可以反转逻辑,并对帧[1]应用
lower

frames[1].lower()

代替
frames[2]。提升(frames[1])

您可以反转逻辑,并将
lower
应用于
frames[1]

frames[1].lower()
代替
frames[2]。lift(frames[1])

您可以调用
lift()
,而无需按所需顺序为所有帧指定参数:

for idx in [0,2,1]:
    frames[idx].lift()
您可以调用
lift()

for idx in [0,2,1]:
    frames[idx].lift()

嗯,我试过了。这样做的目的是将帧[1]
放在选项卡顺序的第一位,因此第一个
移动到小部件5。我可能会这么做,但还不确定。否则我发现了这个,嗯。只是试了一下。这样做的目的是将帧[1]放在选项卡顺序的第一位,因此第一个
移动到小部件5。我可能会这样做,但还不确定。否则我发现了@PRMoureu的可能副本-谢谢,但用例略有不同。这是一个我找到并测试了我的需要。请注意,它特别引用在单个框架中打包多个小部件,而不是在多个框架中打包。当我从中执行代码时,它按预期工作。但是,在我的示例中,以相同的方式执行它会生成我注意到的异常。它似乎可以与
new\u order=(frames[0]、frames[2]、frames[1])
一起工作,或者以@Novel提供的相同方式工作……现在我这样做了,您是正确的:它以相同的方式工作。但是为什么简单的
obj1.lift(obj0)
不能像预期的那样工作呢?可能是@PRMoureu的重复-谢谢,但用例略有不同。这是一个我找到并测试了我的需要。请注意,它特别引用在单个框架中打包多个小部件,而不是在多个框架中打包。当我从中执行代码时,它按预期工作。但是,在我的示例中,以相同的方式执行它会生成我注意到的异常。它似乎可以与
new\u order=(frames[0]、frames[2]、frames[1])
一起工作,或者以@Novel提供的相同方式工作……现在我这样做了,您是正确的:它以相同的方式工作。但是为什么简单的
obj1.lift(obj0)
不能像预期的那样工作呢?这似乎是可行的。这不是一个最佳的解决方案,但它会很好地工作。我更愿意只执行一次提升。这似乎是可行的。这不是一个最佳的解决方案,但它会很好地工作。我宁愿只执行一次提升。