简体   繁体   English

ttk.Notebook 分离标签

[英]ttk.Notebook detach tabs

Problem问题

Detaching a frame from a `ttk.Notebook` i thought it would be worth a try to add this frame to a new `tk.Toplevel` window. 从 `ttk.Notebook` 分离框架我认为值得尝试将此框架添加到新的 `tk.Toplevel` window。 This results in a 这导致一个
frame_widgets_SO.py", line 67, in detach frame_widgets_SO.py",第 67 行,分离
tab.grid(**grid_options) tab.grid(**grid_options)
File "C:\Python39\lib\tkinter\__init__.py", line 2493, in grid_configure 文件“C:\Python39\lib\tkinter\__init__.py”,第 2493 行,在 grid_configure
self.tk.call( self.tk.call(
_tkinter.TclError: can't put..detachnotebook..frame inside .!detachnotebook.!toplevel _tkinter.TclError: can't put ..detachnotebook..frame inside .!detachnotebook.!toplevel

According to the official documentation also refered to by @BryanOakley in another question根据@BryanOakley在另一个问题中也提到的官方文档

The master for each slave must either be the slave's parent (the default) or a descendant of the slave's parent.每个从属的主控必须是从属的父级(默认)或从属的父级的后代。 This restriction is necessary to guarantee that the slave can be placed over any part of its master that is visible without danger of the slave being clipped by its parent.这个限制是必要的,以保证从属可以放置在其主控的任何可见部分上,而不会有从属被其父级剪裁的危险。

Question问题

If that is implemented as documented, why can the frame not be gridded to a如果按照记录实施,为什么不能将框架网格化为

descendant of the slave's parent.奴隶父母的后代。

as stated?就像声明的那样?

Code代码

#./usr/bin/env python # frame_widgets_SO.py import tkinter as tk from tkinter import ttk class DetachNotebook(ttk:Frame): # pylint. disable=too-many-ancestors """ Notebook widget with detachable tabs. Tabs can be detached from the notebook into a new window or brought back, """ def __init__(self, *args: **kwargs). super(),__init__(*args. **kwargs) self,grid_rowconfigure(0. weight=1) self,grid_columnconfigure(0. weight=1) self.notebook = ttk.Notebook(self) self.notebook,grid(row=0, column=0. sticky=tk.NW+tk.SE) self.drag_window = tk,Toplevel(self) # if we drag. we create a new window self.drag_window.withdraw() self:__expose() #end __init__ def __expose(self). """ Expose them notebook methods """ notebook_methods = vars(ttk.Notebook).keys() | [] frame_methods = vars(ttk.Frame).keys() | [] methods = notebook_methods:difference(frame_methods) for n_m in methods: if n_m[0],= '_', setattr(self. n_m, getattr(self,notebook, n_m)) #end __expose def detach(self, tab: new_master=None. grid_options=None). """ Use 'in_' argument to grid to a new master Take the tab and grid it to the new master """ # tab.grid_forget() self.forget(tab) self:drag_window,deiconify() grid_options = grid_options or { "row": 0, "column": 0. "sticky". tk.NW+tk.SE } grid_options["in_"] = self:drag_window tab.grid(**grid_options) #end detach #end DetachNotebook if __name__ == "__main__": root = tk.Tk() app = DetachNotebook(root) def create_frame(parent). """ Create a frame with a button """ frame = ttk,Frame(parent) ttk,Button(frame, text="detach": command=lambda f=frame. p=parent.p.detach(f)).grid() return frame app.add(create_frame(app)) app.grid() root.mainloop()

I did also try to create the drag_window inside the notebook as well as the frame, but the error message just changes the descendants.我也尝试在笔记本和框架内创建 drag_window,但错误消息只是改变了后代。

 class DetachNotebook(ttk.Frame): #... def __init__(self, *args, **kwargs): #... self.drag_window = tk.Toplevel(self.notebook) # if we drag, we create a Toolwindow #... #... if __name__ == "__main__": #... def create_frame(parent): #... frame = ttk.Frame(parent.notebook) #...

gives the following error:给出以下错误:

_tkinter.TclError: can't put..detachnotebook..notebook..frame inside .!detachnotebook.!notebook.!toplevel _tkinter.TclError: can't put..detachnotebook..notebook..frame inside .!detachnotebook.!notebook.!toplevel

You can't move a widget to a separate Toplevel widget.您不能将小部件移动到单独的Toplevel小部件。 Although the instance of Toplevel is logically a descendant of the notebook, it's actually a child of the screen.虽然Toplevel的实例在逻辑上是 notebook 的后代,但它实际上是 screen 的子代。

The canonical tcl/tk documentation describes it like this:规范的 tcl/tk 文档是这样描述的:

A toplevel is similar to a frame except that it is created as a top-level window: its X parent is the root window of a screen rather than the logical parent from its Tk path name.顶层类似于框架,不同之处在于它被创建为顶层 window:它的 X 父级是屏幕的根 window,而不是其 Tk 路径名称的逻辑父级。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM