введите сюда описание изображения Я хочу добиться эффекта, показанного на картинке. Нажмите знак плюса, чтобы добавить тег, нажмите «Закрыть», чтобы закрыть тег.
Я могу сделать это с помощью двух отдельных функций, но не могу сделать это с двумя функциями вместе.
Как мне добиться этого с помощью ttk.Notebook?
Согласно этому методу, моя кнопка «плюс» также имеет значок закрытия, а это не то, что мне нужно.
Чтобы добиться описанного эффекта с помощью ttk.Notebook, вам необходимо создать пользовательскую вкладку, включающую в себя как тег, так и кнопку закрытия. Вот краткий способ сделать это:
Создайте фрейм для вкладки: этот фрейм будет содержать как тег (метку), так и кнопку закрытия. Добавьте рамку в блокнот. Вставьте рамку в ttk.Notebook как вкладку. Привязка кнопки закрытия: прикрепите команду к кнопке закрытия, чтобы удалить вкладку.
пример кода: импортировать tkinter как tk из tkinter import ttk def add_tab():frame = ttk.Frame(notebook) label = ttk.Label(frame, text = "New Tag") label.pack(side = "left") close_btn = ttk.Button(frame, text = "x", команда=lambda: Notebook.forget(frame)) close_btn.pack(side = "right") Notebook.add(frame, text = "") # Корень основного приложения = tk.Tk() блокнот = ttk.Notebook(root) Notebook.pack(expand=True, fill='both') add_button = ttk.Button(root, text = "+", команда=add_tab) add_button.pack() корень.mainloop()
Пожалуйста, разместите код внутри ответа, чтобы он мог сохранить символы новой строки и отступы. Также гораздо проще изменить позже или добавить подсветку синтаксиса.
Спасибо, но эффект, который мне нужен, - это эффект на моей картинке, очевидно, ваш код далек от того, что мне нужно
С помощью tkinter сложно добиться того, чего вы хотите, потому что вам потребуются два типа вкладок: обычные вкладки с кнопкой закрытия и дополнительная вкладка со значком «добавить».
Не слишком сложный способ добиться результата, достаточно похожего на то, что вам хотелось бы, — это взять класс CustomNotebook
из Есть ли способ добавить кнопки закрытия вкладок в tkinter.ttk.Notebook? чтобы получить кнопку закрытия вкладок и добавить дополнительную кнопку «Добавить» в верхнем левом углу блокнота для создания новых вкладок:
class AddBtnNotebook(CustomNotebook):
def __init__(self, *args, **kwargs):
CustomNotebook.__init__(self, *args, **kwargs)
self._img = tk.PhotoImage(data=b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\xb3IDATx\x9c\xb5\xd31j\x82A\x14\x04\xe0\xef\x89v\xb1H)hk*/\x912x\x81\x94\x9e\xc0\xce\xcb\xd8\xeb\xa9\xb41`\x93\x80`J\xc9\xa6QX\x7fw\xe1\x8f\x92\x81)fwf\xd8]\xdeJ))\x11\x0b|\xe1\x13\xf3\xaa\xaf\x12\x9e e\xfc\xc1\xb8\xe4\xed(c\xd4\xd0\x81a\xc9X+h\x8d\x87\x0b\xba\x10\x11]\xf4\xb3\xf5\xa7\x82\xb7\x1f\x11\xcf\x99>\xa6\x94N0\xc5\xc1\xf5\xa3\xb5\xe1\xe1\x9c\xb5\xbd#|\xe16p\xac\x1c\xb9\r\xbe;X\xdd\x19\x86U\xa0\x87w\x0c\xb2\x8d\x17\xcc\x1a\xe6%6\x99\xdec]\x9b\xc47\xb7\xf7}\xfd\xcb$\xb6\xc6\xbf\x15\xec\x1a:\xe1\xa3\xe8|\xf4;\xff\x02/@\xbfn\x03\x8cH\xb7\x00\x00\x00\x00IEND\xaeB`\x82')
self.add_button = ttk.Button(self, image=self._img, command=self.add_tab, padding=0)
self.add_button.place(relx=1, rely=0, anchor = "ne")
def add_tab(self):
frame = tk.Frame(self)
notebook.add(frame, text = "New Tab")
Приведенный выше код также можно напрямую интегрировать в исходный код CustomNotebook
, но я не хотел повторять его здесь, поскольку он уже доступен с пояснениями в Есть ли способ добавить кнопки закрытия вкладок в tkinter.ttk.Notebook ?.
Отказ от ответственности: это решение не очень хорошо обрабатывает изменение размера (кнопка добавления перекрывает вкладки) и не всегда находится рядом с последней вкладкой, как на рисунке в вопросе.
Как было предложено в комментариях @acw1668 , для кнопок закрытия вы можете просто использовать код из этого ответа.
Что касается кнопки «Добавить», то я думаю, что существует несколько способов ее создания. Я покажу вам метод, который создаст дополнительную вкладку «Добавить». Основная идея заключается в том, что вы просто устанавливаете для этого состояния вкладки «Добавить» значение «отключено» и добавляете дополнительную логику в код кнопки закрытия для выполнения специальных действий, если вкладка «отключена».
Добавьте вкладку «Добавить» в метод __init__
:
...
ttk.Notebook.__init__(self, *args, **kwargs)
self.add(tk.Frame(self), state='disabled') # "+" tab
...
Измените метод on_close_press
, чтобы добавить дополнительную логику в случае нажатия кнопки «Добавить»:
...
index = self.index("@%d,%d" % (event.x, event.y))
if self.tab(index, 'state') == 'disabled': # "+" tab is pressed
self.add_new_tab(index)
return "break"
...
Где add_new_tab
ваш метод, создающий новую вкладку.
Теперь добавьте изображение «+» к self.images
:
...
tk.PhotoImage("img_add", data='''
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAA
AARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAB+SURBVChTY2ZA
AyJSxtVcPFJq3748Pw8VAgMmKI0EGHkZGZi4oBw4wKIQOyBaISPITSDroHyG//8Z
7IHkF0ZGxrNQIQZGxv/vmRj+M7xg/M/4FIZBioByH1HE/jO9hGhBAiJSJh2ikqa5
UC4cUN8zGApBDmdgZPgM5UIBAwMAe9MjkX8aHzEAAAAASUVORK5CYII=''')
...
И, наконец, просто добавьте дополнительный «отключенный» регистр в element_create
:
...
("disabled", "img_add"),
...
Полный код (с примером метода add_new_tab
):
class CustomNotebook(ttk.Notebook):
"""A ttk Notebook with close buttons on each tab"""
__initialized = False
def __init__(self, *args, **kwargs):
if not self.__initialized:
self.__initialize_custom_style()
self.__inititialized = True
kwargs["style"] = "CustomNotebook"
ttk.Notebook.__init__(self, *args, **kwargs)
self.add(tk.Frame(self), state='disabled') # "+" tab
self._active = None
self.bind("<ButtonPress-1>", self.on_close_press, True)
self.bind("<ButtonRelease-1>", self.on_close_release)
def on_close_press(self, event):
"""Called when the button is pressed over the close button"""
element = self.identify(event.x, event.y)
if "close" in element:
index = self.index("@%d,%d" % (event.x, event.y))
if self.tab(index, 'state') == 'disabled': # "+" tab is pressed
self.add_new_tab(index)
return "break"
self.state(['pressed'])
self._active = index
return "break"
def on_close_release(self, event):
"""Called when the button is released"""
if not self.instate(['pressed']):
return
element = self.identify(event.x, event.y)
if "close" not in element:
# user moved the mouse off of the close button
return
index = self.index("@%d,%d" % (event.x, event.y))
if self._active == index:
self.forget(index)
self.event_generate("<<NotebookTabClosed>>")
self.state(["!pressed"])
self._active = None
def add_new_tab(self, add_index):
"""Adds a new tab on button "+" pressed"""
pass
# Your code for the new tab there. Example:
self.insert(add_index, tk.Label(text='Just a test tab'), text='NewTab')
self.select(add_index)
def __initialize_custom_style(self):
style = ttk.Style()
self.images = (
tk.PhotoImage("img_close", data='''
R0lGODlhCAAIAMIBAAAAADs7O4+Pj9nZ2Ts7Ozs7Ozs7Ozs7OyH+EUNyZWF0ZWQg
d2l0aCBHSU1QACH5BAEKAAQALAAAAAAIAAgAAAMVGDBEA0qNJyGw7AmxmuaZhWEU
5kEJADs=
'''),
tk.PhotoImage("img_closeactive", data='''
R0lGODlhCAAIAMIEAAAAAP/SAP/bNNnZ2cbGxsbGxsbGxsbGxiH5BAEKAAQALAAA
AAAIAAgAAAMVGDBEA0qNJyGw7AmxmuaZhWEU5kEJADs=
'''),
tk.PhotoImage("img_closepressed", data='''
R0lGODlhCAAIAMIEAAAAAOUqKv9mZtnZ2Ts7Ozs7Ozs7Ozs7OyH+EUNyZWF0ZWQg
d2l0aCBHSU1QACH5BAEKAAQALAAAAAAIAAgAAAMVGDBEA0qNJyGw7AmxmuaZhWEU
5kEJADs=
'''),
tk.PhotoImage("img_add", data='''
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAA
AARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAB+SURBVChTY2ZA
AyJSxtVcPFJq3748Pw8VAgMmKI0EGHkZGZi4oBw4wKIQOyBaISPITSDroHyG//8Z
7IHkF0ZGxrNQIQZGxv/vmRj+M7xg/M/4FIZBioByH1HE/jO9hGhBAiJSJh2ikqa5
UC4cUN8zGApBDmdgZPgM5UIBAwMAe9MjkX8aHzEAAAAASUVORK5CYII=''') # "+" image
)
style.element_create("close", "image", "img_close",
("active", "pressed", "!disabled", "img_closepressed"),
("active", "!disabled", "img_closeactive"),
("disabled", "img_add"), border=8, sticky='')
style.layout("CustomNotebook", [("CustomNotebook.client", {"sticky": "nswe"})])
style.layout("CustomNotebook.Tab", [
("CustomNotebook.tab", {
"sticky": "nswe",
"children": [
("CustomNotebook.padding", {
"side": "top",
"sticky": "nswe",
"children": [
("CustomNotebook.focus", {
"side": "top",
"sticky": "nswe",
"children": [
("CustomNotebook.label", {"side": "left", "sticky": ''}),
("CustomNotebook.close", {"side": "left", "sticky": ''}),
]
})
]
})
]
})
])
И последнее: помните, что кнопка «Добавить» — это вкладка, поэтому, если вы добавите другие вкладки с помощью команды Notebook.add()
, новые вкладки будут добавлены после вкладки «Добавить». Вместо этого вы можете использовать команду notebook. insert()
.
Примечание. Этот код еще можно улучшить. Например, вы можете добавить дополнительное изображение (и логику), чтобы сделать вкладку «Добавить» более динамичной, точно так же, как это делается с кнопками «закрыть».
Прекрасно работает! Спасибо!
О кнопке закрытия см. этот вопрос: есть ли способ добавить кнопки закрытия на вкладки в тетради tkinter-ttk-n.