Python 3.5 tkinter:将窗口小部件调整为窗口

时间:2016-07-25 14:03:18

标签: python tkinter resize grid-layout

我正在阅读,阅读和阅读,但仍无法找到适合我的问题的答案。我打算创建一个'Masterwindow',在其中我实现了几个框架(当前是左侧的导航面板,一个'RootFrame',当没有进程运行时显示,底部有一个状态栏,用于警报和处理)一个主框架。运行下面的代码,一切正常,但框架不适应窗口的大小调整。

现在,我知道,我需要在主类和子类中做一些操作,并将grid_column-和rowconfigure设置为权重> 0但仍然没有任何反应。

我看不出原因。我错过了什么?我是否需要将所有内容放入另一个主机?我坚持主窗口?这是不对的,因为我在各处都继承了框架......

感谢您的努力和投入。 RGDS

ps:哦顺便说一句:任何人都可以告诉我如何在网格方法中迭代行,这样我就可以简单地说'在下一行中构建小部件'(相对)并且不必使用绝对整数?

    # -*- coding: UTF-8 -*-

    import tkinter.ttk
    from tkinter import *


    class MainApplication(tkinter.Frame):
        @classmethod
        def main(cls):
            root = tkinter.Tk()
            app = cls(root)
            app.master.title('Sample')
            root.resizable(True, True)
            root.mainloop()

        def __init__(self, parent=None, *args, **kwargs):
            tkinter.Frame.__init__(self, parent, *args, **kwargs)
            self.grid(sticky=N+E+S+W)

            # Var-Declaration
            self.h = 600
            self.w = 1200
            self.widget_fr_opts = dict(relief='groove', borderwidth=1, bg='#EFEFFB')

            #  Widget-Creation
            self.rootframe = RootFrame(self)
            self._visible_ = self.rootframe  # internal updater what frame is visible - starting with rootframe on init
            self.statusbar = Statusbar(self)
            self.navbar = Navbar(self)
            self.main_db = MainDB(self)

            #  Widget-Design

            # Widget-Arrangement
            self.grid_rowconfigure(0, minsize=self.h * 0.95)
            self.grid_rowconfigure(1, minsize=self.h * 0.05)
            self.grid_columnconfigure(0, minsize=self.w*0.15)
            self.grid_columnconfigure(1, minsize=self.w*0.85)
            self.navbar.grid(sticky=N+S+E+W, column=0, row=0)
            self.main_db.grid(sticky=N+E+S+W, column=1, row=0)
            self.rootframe.grid(sticky=N+E+S+W, column=1, row=0)
            self.statusbar.grid(sticky=W+E, column=0, columnspan=2, row=1)

            self.grid_columnconfigure(1, weight=1)
            self.statusbar.columnconfigure(0, weight=1)
            self.rootframe.columnconfigure(0, weight=1)
            self.main_db.columnconfigure(0, weight=1)

            self.grid_rowconfigure(0, weight=1)
            self.navbar.rowconfigure(4, weight=1)
            self.rootframe.rowconfigure(0, weight=1)
            self.main_db.rowconfigure(0, weight=1)

            self.rootframe.lift(self.main_db)

        def visualize(self, master):
            """Lifts master to upper Level"""
            master.lift(self.rootframe)
            self._visible_ = master

        def event_handler(self):
            pass

        def start_subapp(self, app):
            self.visualize(app)
            app.activate_content()


    class RootFrame(tkinter.Frame):
        """General Launcher Frame as a Placeholder"""

        def __init__(self, parent, *args, **kwargs):
            tkinter.Frame.__init__(self, parent, *args, **kwargs)

            #  Var-Daclaration
            self.widget_fr_opts = dict(relief='sunken', borderwidth=1)
            self.widget_grid_opts = dict(sticky=N+E+S+W, padx=1, pady=1)

            #  Widget-Creation
            self.Image = tkinter.ttk.Label(self, text='there would be a centered image right here', anchor='center')

            #  Widget-Design
            self.configure(**self.widget_fr_opts)

            #  Widget-Arrangement
            self.Image.grid(column=0, row=0, **self.widget_grid_opts)

            self.grid_columnconfigure(0, weight=1)
            self.grid_rowconfigure(0, weight=1)


    class Navbar(tkinter.Frame):
        """vertical NavBar"""

        def __init__(self, parent, *args, **kwargs):
            tkinter.Frame.__init__(self, parent, *args, **kwargs)

            #  Var-Daclaration
            self._info_ = tkinter.StringVar()
            self.widget_fr_opts = dict(relief='groove', borderwidth=1)
            self.widget_grid_opts = dict(sticky=N+E+S+W, padx=1, pady=1)
            self.widget_grid_subopts = dict(sticky=W+N+E, padx=1, pady=1)
            self._statusbar = parent.statusbar

            #  Widget-Creation
            self._info_.set('Menu:\n...Menusentences:')
            self.TextInfo = tkinter.ttk.Label(self, textvariable=self._info_)
            self.Btn_Progress = tkinter.ttk.Button(self, text='Start Progress',
                                                   command=lambda: self.statusbar_input('Starting progress ...'))   # some code being started
            self.Btn_Database = tkinter.ttk.Button(self, text='Database',
                                                   command=lambda: parent.start_subapp(parent.main_db))  # Database window is lifted and content initialized
            self.Btn_Exit = tkinter.ttk.Button(self, text='Exit', command=parent.quit)

            #  Widget-Design
            self.configure(**self.widget_fr_opts)

            #  Widget-Arrangement
            self.TextInfo.grid(column=0, row=1, **self.widget_grid_subopts)
            self.Btn_Progress.grid(column=0, row=2, **self.widget_grid_subopts)
            self.Btn_Database.grid(column=0, row=3, **self.widget_grid_subopts)
            self.Btn_Exit.grid(column=0, row=4, **self.widget_grid_subopts)

            self.grid_columnconfigure(0, weight=1)
            self.grid_rowconfigure(0, weight=0)
            self.grid_rowconfigure(1, weight=0)
            self.grid_rowconfigure(2, weight=0)
            self.grid_rowconfigure(3, weight=0)
            self.grid_rowconfigure(4, weight=0)

        def statusbar_input(self, comm: str):
            self._statusbar.start()
            self._statusbar._info_.set(comm)


    class Statusbar(tkinter.Frame):
        """Status-Bar at the bottom"""

        def __init__(self, parent, *args, **kwargs):
            tkinter.Frame.__init__(self, parent, *args, **kwargs)

            #  Var-Daclaration
            self.prgrvalue = tkinter.IntVar()
            self._info_ = tkinter.StringVar()
            self._user_ = 'some user'
            self.widget_fr_opts = dict(relief='sunken', borderwidth=1)
            self.widget_grid_opts = dict(padx=1, pady=1)
            self.widget_grid_subopts = dict(padx=1, pady=1)  # sticky=W + E,

            #  Widget-Creation
            self._info_.set('Initializing ...')
            self.prgrvalue.set(0)
            self.TextInfo = tkinter.ttk.Label(self, textvariable=self._info_)
            self.UserInfo = tkinter.ttk.Label(self, textvariable=self._user_)
            self.progress_ = tkinter.ttk.Progressbar(self)
            self.Btn_Move = tkinter.ttk.Button(self, text='Move it', command=lambda: self.start())  # just for initial testing, will be removed later
            self.Btn_Stop = tkinter.ttk.Button(self, text='Stop it', command=lambda: self.stop())

            #  Widget-Design
            self.configure(**self.widget_fr_opts)
            self.progress_.configure(length=200, mode='determinate', orient=tkinter.HORIZONTAL)

            #  Widget-Arrangement
            self.progress_.grid(sticky=W+E, column=0, row=0, **self.widget_grid_subopts)
            self.TextInfo.grid(column=1, row=0, **self.widget_grid_subopts)
            self.UserInfo.grid(column=2, row=0, padx=1, pady=1)  # sticky=E,
            self.Btn_Move.grid(column=3, row=0, **self.widget_grid_subopts)
            self.Btn_Stop.grid(column=4, row=0, **self.widget_grid_subopts)
            self.grid_columnconfigure(0, weight=1)
            self.grid_columnconfigure(1, minsize=200)
            self.grid_columnconfigure(2, minsize=200)

        def start(self):
            # just testing
            self.progress_.start()

        def stop(self):
            # just testing
            self.progress_.stop()


    class MainDB(tkinter.Frame):
        """Frame for visualizing database."""

        def __init__(self, parent, *args, **kwargs):
            tkinter.Frame.__init__(self, parent, *args, **kwargs)

            #  Var-Daclaration
            self._activated_ = False
            self._source_ = None
            self.combotext = tkinter.StringVar()
            self.combotext.set('Please choose a tab...')
            self.widget_fr_opts = dict(relief='sunken', borderwidth=1)
            self.widget_grid_opts = dict(sticky=N+E+S+W, padx=1, pady=1)

            #  Widget-Creation
            #  CREATION OF TOOLS TO MANIPULATE DATABASE
            self.toolframe = tkinter.Frame(self, width=100, height=50, relief='groove', borderwidth=1)
            self.combo = tkinter.ttk.Combobox(self.toolframe, textvariable=self.combotext)
            # more to come

            #  CREATION OF DATABASE'WINDOW
            self.dbframe = tkinter.Frame(self, width=100, relief='groove', borderwidth=1)
            self.db_treeview = tkinter.ttk.Treeview(self.dbframe, columns=('size', 'modified'), selectmode='extended')
            #  more to come

            #  Widget-Design

            #  Widget-Arrangement
            self.toolframe.grid(column=0, row=0, sticky=N+E+W, padx=1, pady=1)
            self.combo.grid(column=0, row=0, sticky=N+E, padx=1, pady=1)
            self.dbframe.grid(column=0, row=1,  sticky=NSEW, padx=1, pady=1)
            self.db_treeview.grid(column=0, row=0, sticky=NSEW, padx=1, pady=1)

            self.grid_columnconfigure(0, weight=1)
            self.grid_rowconfigure(0, weight=0)
            self.grid_rowconfigure(1, weight=1)
            self.dbframe.grid_columnconfigure(0, weight=1)
            self.dbframe.grid_rowconfigure(0, weight=1, minsize=600)
            self.toolframe.grid_columnconfigure(0, weight=1)
            self.toolframe.grid_rowconfigure(0, weight=1)

        def activate_content(self):
            #  some contentloading and initializations
            pass

        def db_connector(self, comm: str, save=False) -> bool:
            #  some connection code
            pass


    if __name__ == '__main__':

        UserScreen = MainApplication.main()

1 个答案:

答案 0 :(得分:1)

您忽略了对根窗口中的任何行或列赋予权重。没有它,tkinter在你调整窗口大小时不知道如何分配额外的空间。

def main(cls):
    ...
    root.grid_rowconfigure(0, weight=1)
    root.grid_columnconfigure(0, weight=1)

由于您只在根窗口中放置了一个小部件,因此我建议您使用pack,因为您可以在一行中完成所有操作。

    self.pack(fill="both", expand=True)