【问题标题】:How to make the tkinter window responsive with the widgets placed using pack() method in Tkinter Python?如何使 tkinter 窗口响应在 Tkinter Python 中使用 pack() 方法放置的小部件?
【发布时间】:2021-08-20 14:44:07
【问题描述】:

我希望当 GUI 窗口的大小根据显示器大小增加或减少时,我的 gui 小部件得到管理。

使用我当前的代码,这个窗口在我的显示器中看起来像这样 --- Look of the gui when open in my pc

当在另一个相同大小的监视器屏幕中打开相同的 GUI 程序时,窗口的某些部分会被截断 -- Look of the gui window in another pc monitor

但我希望我的 GUI 窗口能够通过监视器屏幕调整其所有小部件。

请帮我解决这个问题,并请建议我应该在我的代码中添加什么以使其响应!!

注意 - 我使用了 pack() 方法来放置标签框

我的某行代码---

class Application:
def __init__(self, root):
    self.root = root
    self.root.title("Auto-Garage Management Application")
    self.screen_width = self.root.winfo_screenwidth()
    self.screen_height = self.root.winfo_screenheight()
    self.root.geometry("%dx%d+-10+0" % (self.screen_width, self.screen_height))

    bg_color1 = "#ff704d"
    bg_color2 = "powder blue"

    # =============== Fonts
    frame_label_font = Font(family="Poppins", size=20, weight="bold")
    entry_label_font1 = Font(family="Roboto", size=17, weight="bold")
    entry_label_font2 = Font(family="Roboto", size=15, weight="bold")
    entry_font = Font(family="Noto Sans", size=15, weight="bold")
    btn_font = Font(family="Noto Sans", size=15, weight="bold")

    # ================ Variables 
    # Customer Details
    self.customer_name = StringVar()
    self.customer_phone = StringVar()
    self.customer_telno = StringVar()
    self.customer_address_1 = StringVar()
    self.customer_address_2 = StringVar()
    self.customer_address_3 = StringVar()
    
    # ========== Customer Details
    customer_details_frame = LabelFrame(self.root, text="Customer Details", bg=bg_color1, fg="black",
                                        font=frame_label_font, bd=6, relief=GROOVE)
    customer_details_frame.pack(fill=BOTH)

    # Customer Name
    customer_name = Label(customer_details_frame, text="Customer Name", bg=bg_color1, fg="yellow", font=entry_label_font1)
    customer_name.grid(row=0, column=0, padx=20, pady=5)

    customer_name_txt = Entry(customer_details_frame, textvariable=self.customer_name, width=22, font=entry_font, bd=5, relief=SUNKEN)
    customer_name_txt.grid(row=0, column=1, padx=10)

    # Customer Phone Number
    customer_phone = Label(customer_details_frame, text="Customer Phone", bg=bg_color1, fg="yellow", font=entry_label_font1)
    customer_phone.grid(row=0, column=2, padx=20, pady=5)

    customer_phone_txt = Entry(customer_details_frame, textvariable=self.customer_phone, width=22, font=entry_font, bd=5, relief=SUNKEN)
    customer_phone_txt.grid(row=0, column=3, padx=10)

    customer_phone2 = Label(customer_details_frame, text="Customer Tel No.", bg=bg_color1, fg="yellow", font=entry_label_font1)
    customer_phone2.grid(row=1, column=2, padx=10)

    customer_phone2_txt = Entry(customer_details_frame, textvariable=self.customer_telno, width=22, font=entry_font, bd=5, relief=SUNKEN)
    customer_phone2_txt.grid(row=1, column=3, padx=10)

    # Customer Address
    customer_address = Label(customer_details_frame, text="Customer Address", bg=bg_color1, fg="yellow", font=entry_label_font1)
    customer_address.grid(row=0, column=4, padx=20, pady=5)

    customer_address_txt1 = Entry(customer_details_frame, textvariable=self.customer_address_1, width=22, font=entry_font, bd=5, relief=SUNKEN)
    customer_address_txt1.grid(row=0, column=5, padx=10)

    customer_address_txt2 = Entry(customer_details_frame, textvariable=self.customer_address_2, width=22, font=entry_font, bd=5, relief=SUNKEN)
    customer_address_txt2.grid(row=1, column=5, padx=10)

    customer_address_txt3 = Entry(customer_details_frame, textvariable=self.customer_address_3, width=22, font=entry_font, bd=5, relief=SUNKEN)
    customer_address_txt3.grid(row=2, column=5, padx=10, pady=5)

    app = Tk()
    software = Application(app)
    app.mainloop()

感谢您的帮助!!!

【问题讨论】:

  • 向我们展示一些代码会有所帮助。
  • 我认为使用 tkinter 创建响应式布局并不容易。
  • 我还能用什么来在 python 中而不是 tkinter 中制作响应式 gui??
  • @acw1668:这取决于您如何定义“响应式”。制作适合多种窗口大小的 UI 非常容易。然而,让字体自动放大或缩小需要更多的工作。不过还是可以的。
  • 看起来您的问题主要是由于使用了对于较小的显示器来说太大的硬编码字体。简单的答案似乎是“使用较小的字体”。如果没有看到我们可以用来查看您如何创建 GUI 的最小示例,我们将很难为您提供更好的建议。

标签: python oop tkinter


【解决方案1】:

我有一个建议。

您可以将它分成几部分并使 GUI 变小,而不是构建一个在一个屏幕上完成所有工作的又大又长的 GUI。 (从 1000x800 到 600x400 我猜显示器不能比这个小

喜欢:

  1. 在小 GUI 中首先获取客户详细信息。
  2. 然后是车辆详细信息等

或:

Use HTML, CSS, JS to create a responsive GUI(as its much easier to make responsive GUI using HTML, CSS and JS than in tkinter

【讨论】:

    【解决方案2】:

    packgrid 都有选项可以帮助您定义额外空间的去向,以及小部件如何在给定的空间中增长、缩小和对齐。创建一个有点响应的布局只需要仔细使用这些选项。

    您似乎也在使用硬编码的字体大小。可以获取窗口大小,然后选择适合窗口大小的字体大小。

    布置小部件。

    虽然模拟整个 UI 需要太多代码,但下面是我创建顶部面板的方法。请注意如何为带有条目小部件的列赋予权重,以便在有任何额外空间时它们会增长。我还使用sticky 选项来确保它们填满给它们的空间。

    class CustomerDetails(tk.LabelFrame):
        def __init__(self, parent, *args, **kwargs):
            super().__init__(parent, *args, **kwargs)
            self.name = tk.Entry(self)
            self.phone = tk.Entry(self)
            self.telno = tk.Entry(self)
            self.addr1 = tk.Entry(self)
            self.addr2 = tk.Entry(self)
            self.addr3 = tk.Entry(self)
    
            name_label = tk.Label(self, text="Customer Name")
            phone_label = tk.Label(self, text="Customer Phone")
            telno_label = tk.Label(self, text="Customer Tel No.")
            addr_label = tk.Label(self, text="Customer Address")
    
            self.grid_columnconfigure((1,3,5), weight=1)
    
            name_label.grid(row=0, column=0, sticky="e")
            phone_label.grid(row=0, column=2, sticky="e")
            telno_label.grid(row=1, column=2, sticky="e")
            addr_label.grid(row=0, column=4, sticky="e")
    
            self.name.grid(row=0, column=1, sticky="ew")
            self.phone.grid(row=0, column=3, sticky="ew")
            self.telno.grid(row=1, column=3, sticky="ew")
            self.addr1.grid(row=0, column=5, sticky="ew")
            self.addr2.grid(row=1, column=5, sticky="ew")
            self.addr3.grid(row=2, column=5, sticky="ew")
    

    然后您可以使用pack 将此小部件添加到根窗口,如下例所示。请注意它如何定义 fillexpand 选项来控制它在不完全适合窗口时的行为。

    root = tk.Tk()
    details = CustomerDetails(root, text="Customer Details")
    details.pack(side="top", fill="x", expand=False)
    

    如果您运行此代码,您会注意到小部件都适合非常窄和非常宽的窗口。当然,如果窗口太小,那么入口小部件就会变得无法使用。

    动态改变字体大小。

    默认情况下,标签将使用名为TkDefaultFont 的字体,条目和文本小部件使​​用TkTextFont。如果您依赖这些默认设置,您可以更改字体,所有小部件都会相应更改。然后,您可以在创建 UI 之前获取显示的大小并选择正确的大小,或者您可以设置它,以便在调整窗口大小时,字体会自动更改。

    要获得对字体的引用,您可以使用font 模块中的nameToFont 方法。从那里您可以更改所需字体的任何属性:系列、大小等。下面是一个简单的函数示例,该函数根据屏幕大小设置默认字体的大小:

    def initialize_fonts():
        font_size = 12 if root.winfo_screenwidth() <= 1200 else 32
        for font_name in ("TkDefaultFont", "TkTextFont"):
            font = tkFont.nametofont(font_name)
            font.configure(size=font_size)
    

    如果您在创建任何小部件之前调用此函数,它们都将使用新大小创建。

    root = tk.Tk()
    initialize_fonts()
    details = CustomerDetails(root, text="Customer Details")
    details.pack(side="top", fill="x", expand=False)
    

    【讨论】:

    • 意味着首先我必须为框架创建类,然后通常设置它们的列配置等?通过这样做,小部件将缩小并适合窗口?
    • 我已经在问题部分发布了我的一些代码。你能告诉我我应该如何让它响应我的情况吗?
    • @TirthPatel:遵循我在回答中给出的建议:使用条目小部件配置列的权重,并使用 sticky 属性。
    • @TirthPatel:这可能是因为您还没有修改它以使用您的字体。当我写那个答案时,我不知道你使用的是什么字体。不要复制代码,复制概念。
    • 我使用了从 tkinter.font 导入的字体,我怎样才能让它工作?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多