简体   繁体   English

获取按钮以与python ttk笔记本中的选项卡对齐

[英]Get a button to align with tabs in python ttk notebook

I have an app, where I need to add a create_new_tab button, which trails the last tab of the notebook widget. 我有一个应用程序,需要在其中添加一个create_new_tab按钮,该按钮位于笔记本小部件的最后一个标签后面。 However all my attempts using pack have failed. 但是我所有使用pack的尝试都失败了。 I have packed the notebook using pack. 我已经用背包包装了笔记本。

In the image below, i need the +++ to trail the last tab 在下图中,我需要+++跟踪最后一个选项卡

import Tkinter as GUI
import ttk
import ScrolledText
import commands

app = GUI.Tk()
lang = ''

class DisplayWidget():
    def __init__(self, book):
        """
        :param book: the tabbed notebook
        :return:
        """
        self.book = book
        self.primary_frame = []
        self.frame_codepad = []
        self.frame_outputpad = []
        self.frame_autocomplete = []
        self.bar_editor = []
        self.lb = []
        self.pad = []
        self.linepad = []
        self.inputpad = []
        self.outputpad = []
        self.W1 = []

    def create_tab(self, *args):

        primary_frame = GUI.Frame(self.book)
        frame_codepad = GUI.Frame(primary_frame)
        frame_autocomplete = GUI.Frame(primary_frame)
        frame_outputpad = GUI.Frame(primary_frame)
        W1 = GUI.PanedWindow(frame_codepad, height=30, width=70)
        bar_editor = GUI.Scrollbar(frame_codepad)
        pad = GUI.Text(W1, height=30, width=60, yscrollcommand=bar_editor.set, undo=True)
        pad.config(fg='#f8f8f2', bg='#002b36', insertbackground='white')
        linepad = GUI.Text(frame_codepad, height=30, width=4, yscrollcommand=bar_editor.set, undo=True)
        linepad.config(fg='#f8f8f2', bg='#002b36', insertbackground='white', state=GUI.DISABLED)
        lb = GUI.Listbox(frame_autocomplete, height=4, width=120)
        lb.config(fg='gray', bg='#002b36')
        inputpad = GUI.Text(W1, height=30, width=30)
        inputpad.config(fg='white', bg='#002b36', insertbackground='white')

        W1.add(pad)
        W1.add(inputpad)

        def share_bar(*event):
            """
            the linenumber abd code textpads share same scrollbar
            :param event: event
            """
            pad.yview(*event)
            linepad.yview(*event)

        bar_editor.config(command=share_bar)

        outputpad = ScrolledText.ScrolledText(frame_outputpad, height=5, width=80)
        outputpad.config(fg='white', bg='#002b36', insertbackground='white', state=GUI.DISABLED)

        primary_frame.pack(side=GUI.LEFT, fill=GUI.BOTH, expand=GUI.YES)
        frame_codepad.pack(side=GUI.TOP, fill=GUI.BOTH, expand=GUI.YES)
        linepad.pack(side=GUI.LEFT, fill=GUI.Y)
        W1.pack(side=GUI.LEFT, fill=GUI.BOTH, expand=GUI.YES)
        bar_editor.pack(side=GUI.LEFT, fill=GUI.Y)
        frame_autocomplete.pack(side=GUI.TOP, fill=GUI.BOTH, expand=GUI.YES)
        lb.pack(side=GUI.TOP, fill=GUI.BOTH, expand=GUI.YES)

        self.book.add(primary_frame, text='untitled.cpp')

        self.primary_frame.append(primary_frame)
        self.frame_codepad.append(frame_codepad)
        self.frame_outputpad.append(frame_outputpad)
        self.frame_autocomplete.append(frame_autocomplete)
        self.bar_editor.append(bar_editor)
        self.lb.append(lb)
        self.pad.append(pad)
        self.linepad.append(linepad)
        self.inputpad.append(inputpad)
        self.outputpad.append(outputpad)
        self.W1.append(W1)

    def destroy_tab(self):
        index = self.book.index(self.book.select())
        self.book.forget(self.book.select())
        self.primary_frame.pop(index)
        self.frame_codepad.pop(index)
        self.frame_outputpad.pop(index)
        self.frame_autocomplete.pop(index)
        self.bar_editor.pop(index)
        self.lb.pop(index)
        self.pad.pop(index)
        self.linepad.pop(index)
        self.inputpad.pop(index)
        self.outputpad.pop(index)
        self.W1.pop(index)


def main():
    commands.setKeys()
    display = commands.CodeDisplay()
    cmd_file = commands.FilesFileMenu()
    edit = commands.EditFileMenu()
    run = commands.RunFilemenu()

    book = ttk.Notebook(app)

    def useless():
        print 'sexy'

    def index():
        return book.index(book.select())

    def change_lang(newlang):
        """
        changes current language in editor
        :param newlang: language to switch to
        :return:
        """
        global lang
        lang = newlang
        # r = map(str, app.title().split('.'))
        # if lang == 'c++' and r[-1] == 'py':
        #     app.title('untitled.cpp')
        #     cmd_file.set_new_filedetails('untitled.cpp', os.getcwd() + '/untitled.cpp')
        #     print File.name, File.path
        # if lang == 'py' and r[-1] == 'cpp':
        #     app.title('untitled.py')
        #     cmd_file.set_new_filedetails('untitled.py', os.getcwd() + '/untitled.py')

    change_lang('c++')

    code = DisplayWidget(book)
    code.create_tab()

    menubar = GUI.Menu(app)
    filemenu = GUI.Menu(menubar, tearoff=0)
    filemenu.add_command(label='New', command=useless)
    filemenu.add_command(label='New Tab', command=lambda: cmd_file.create_new_tab(code))
    filemenu.add_command(label='Close Tab', command=lambda: cmd_file.close_tab(code))
    filemenu.add_command(label='Open', command=lambda: cmd_file.Open(
        app, book, code.pad[index()], code.linepad[index()], lang))
    filemenu.add_command(label='Save', command=lambda: cmd_file.Save(
        app, code.pad[index()]))
    filemenu.add_command(label='Save As', command=lambda: cmd_file.Save_As(
        app, code.pad[index()]))
    filemenu.add_command(label='Exit', command=cmd_file.Exit)
    menubar.add_cascade(label='File', menu=filemenu)

    editmenu = GUI.Menu(menubar, tearoff=0)
    editmenu.add_command(label='Undo - (ctrl+z)', command=lambda: edit.undo(
        code.pad[index()], code.linepad[index()]))
    editmenu.add_command(label='Redo - (ctrl+r)', command=lambda: edit.redo(
        code.pad[index()], code.linepad[index()]))
    menubar.add_cascade(label='Edit', menu=editmenu)

    runmenu = GUI.Menu(menubar, tearoff=0)
    runmenu.add_command(label='Compile - (F7)', command=lambda: run.compile(
        app, code.pad[index()], code.outputpad[index()], lang, code.frame_outputpad[index()]))
    runmenu.add_command(label='Run - (F5)', command=lambda: run.run(
        app, code.pad[index()], code.outputpad[index()], code.inputpad[index()], lang, code.frame_outputpad[index()]))
    menubar.add_cascade(label='Run', menu=runmenu)

    langmenu = GUI.Menu(menubar, tearoff=0)
    langmenu.add_radiobutton(label='c++', command=lambda: change_lang('c++'))
    langmenu.add_radiobutton(label='python', command=lambda: change_lang('py'))
    menubar.add_cascade(label='Language', menu=langmenu)

    app.bind('<Escape>', lambda event: display.escape(
        code.frame_autocomplete[index()], code.pad[index()], event))
    app.bind('<Down>', lambda event: display.select_first(
        code.frame_autocomplete[index()], code.lb[index()], code.pad[index()], event))

    code.frame_autocomplete[index()].bind('<Return>', lambda event: display.insert_word(
        code.frame_autocomplete[index()], code.pad[index()], code.lb[index()], lang, event))

    code.pad[index()].bind('<Tab>', lambda event: display.tab_width(code.pad[index()], event))

    app.bind('<KeyPress>', lambda event: display.show_in_console(
        app, book, event, code.pad[index()], code.linepad[index()], lang, code.lb[index()],
        code.frame_codepad[index()], code.W1[index()], code.bar_editor[index()],
        code.frame_outputpad[index()], code.frame_autocomplete[index()], code.outputpad[index()]))

    app.bind('<space>', lambda event: display.add_to_trie(
        code.frame_autocomplete[index()], code.pad[index()], code.lb[index()], event))
    app.bind('<Return>', lambda event: display.indentation(
        code.pad[index()], code.linepad[index()], lang, event))
    app.bind('<F7>', lambda event: run.compile(
        app, code.pad[index()], code.outputpad[index()], lang, code.frame_outputpad[index()], event))
    app.bind('<F5>', lambda event: run.run(
        app, code.pad[index()], code.outputpad[index()], code.inputpad[index()],
        lang, code.frame_outputpad[index()], event))

    app.bind('<Control-r>', lambda event: edit.redo(
        code.pad[index()], code.linepad[index()], lang, event))
    app.bind('<Control-z>', lambda event: edit.undo(
        code.pad[index()], code.linepad[index()], lang, event))
    app.bind('<BackSpace>', lambda event: display.fast_backspace(
        code.pad[index()], code.linepad[index()], event))

    new_tab_button = GUI.Button(book,text = '+++')
    new_tab_button.grid(row = 1, column = 3)

    book.pack(side=GUI.TOP, fill=GUI.BOTH, expand=GUI.YES)
    app.config(menu=menubar)


if __name__ == '__main__':
    main()
    app.title('untitled.cpp')
    app.mainloop()

应用程式

I'm not sure if you can get the button to trail the last tab of the Notebook. 我不确定是否可以单击该按钮以跟踪笔记本的最后一个选项卡。 So what I suggest is using a tab as a button instead. 所以我建议使用选项卡代替按钮。

Example Code: 示例代码:

import tkinter as tk
from tkinter import ttk

def add_tab(event):
    all_tabs = note.tabs() # gets tuple of tab ids
    sel = note.select() # gets id of selected tab

    # if the selected tab is the last tab in the Notebook
    if sel == all_tabs[-1]:
        # Change the text from '+++' to 'New Tab'
        note.tab(sel, text = 'New Tab')
        # root.nametowidget is used to map the id to widget
        # this shows adding widgets to the existing tab
        tab_id = root.nametowidget(sel)
        tk.Label(tab_id, text = 'This is a new tab').pack()

        # add a new 'New Tab' button
        note.add(tk.Frame(note), text = '+++')

root = tk.Tk()
root.minsize(250, 250)

note = ttk.Notebook(root, height = 200, width = 200)

note.add(tk.Frame(note), text = '+++')

note.pack()
note.bind('<ButtonRelease-1>', add_tab)

root.mainloop()

Actually I found that it's possible to get a button to trail a tab ( much easier to accomplish when tabs are of equal width ) 实际上,我发现可以使用一个按钮跟踪选项卡( 当选项卡的宽度相等时,更容易实现

So basically we need to find out the total combined width of all the tabs, which can be roughly done by taking the length of the text inside each tab. 因此,基本上,我们需要找出所有选项卡的总组合宽度,这可以通过考虑每个选项卡中文本的长度来大致完成。 Then all we need to do is to experiment placing the buttons using the place manager. 然后,我们要做的就是尝试使用place管理器来放置按钮。

Sample code in python-2 ( Simple case : Here tabs are of equal sizes ) python-2中的示例代码(简单情况:此处的标签大小相等)

python
import Tkinter as GUI
import ttk
from ScrolledText import ScrolledText

class displayWidget():
    def __init__(self,book):
        self.frame1 =[]
        self.pad1 = []
        self.pad2 = []
        self.book = book

    def foo(self,pad2,event):
        pass
    def create_tab(self,*args):
        frame1a = GUI.Frame(self.book)
        pad1a = GUI.Text(frame1a,height = 10,width = 90)
        pad2a = GUI.Text(frame1a,height = 10,width = 90)
        frame1a.pack(side=GUI.TOP)
        pad1a.pack(side=GUI.TOP)
        pad2a.pack(side=GUI.TOP)
        pad2a.bind('<KeyPress>',lambda event: self.foo(pad2a,event))

        self.frame1.append(frame1a)
        self.pad1.append(pad1a)
        self.pad2.append(pad2a)
        name = '   Tab   '
        self.book.add(frame1a,text=name)
        self.book.pack(side=GUI.TOP)

    def destory_tab(self,*args):
        index = self.book.index(self.book.select())
        self.book.forget(self.book.select())
        self.frame1.pop(index)
        self.pad1.pop(index)
        self.pad2.pop(index)



app = GUI.Tk()
book = ttk.Notebook(app)
D = displayWidget(book)
new_tab_button = GUI.Button(book,text='+',bg='#228c22',fg='white')
del_tab_button = GUI.Button(book,text='-',bg='red',fg='white')

def add_tab(*args):
    D.create_tab()
    new_tab_button.place_forget()
    new_tab_button.place(x = 50+ 46*(len(book.tabs())-1), y = -0.5)
    del_tab_button.place_forget()
    del_tab_button.place(x = 69 + 46*(len(book.tabs())-1), y = -0.5)

def remove_tab(*args):
    if len(book.tabs()) == 1:
        return
    D.destory_tab()
    new_tab_button.place_forget()
    new_tab_button.place(x = 50+ 46*(len(book.tabs())-1), y = -0.5)
    del_tab_button.place_forget()
    del_tab_button.place(x = 69 + 46*(len(book.tabs())-1), y = -0.5)

D.create_tab()
new_tab_button.bind('<Button-1>',add_tab)
del_tab_button.bind('<Button-1>',remove_tab)
new_tab_button.place(x = 50, y = -0.5)
del_tab_button.place(x = 69, y = -0.5)
app.resizable(height=False,width=False)
app.mainloop()

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

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