简体   繁体   中英

How to make the tkinter window responsive with the widgets placed using pack() method in Tkinter Python?

I want my widgets of my gui to get managed when the size of the GUI Window gets increase or decrease according to the monitor size.

With my current code this window looks like this in my monitor --- Look of the gui when open in my pc

And when the same GUI program is open in another monitor screen of same size, the some part of the window gets cut off -- Look of the gui window in another pc monitor

But I want my GUI Window to adjust all its widgets with the monitor screen.

Please help me with this and please suggest me what should I add to my code to make it responsive !!

Note - I have used pack() method to place the Label Frames

My some line of code ---

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()

Thanks For Any Help !!!

pack and grid both have options that help you define where extra space goes, and how widgets grow, shrink, and align in the space that is given. Creating a layout that is somewhat responsive simply requires careful use of those options.

It appears you're also using a hard-coded font size. It's possible to get the size of the window, and then choose a font size that is appropriate for the window size.

Laying out the widgets.

While it would take far too much code to simulate the entire UI, here's how I would create the top panel. Notice how weight is given to the columns with entry widgets so that they grow if there is any extra space. I also use the sticky option to make sure they fill the space given to them.

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")

You can then add this widget to the root window using pack like in the following example. Notice how it defines both the fill and expand options to control how it behaves when it doesn't exactly fit the window.

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

If you run this code you'll notice that the widgets all fit in both a very narrow and very wide window. Of course, if the window is too small then the entry widgets become unusuable.

Dynamically changing font sizes.

By default, labels will use a font named TkDefaultFont and entry and text widgets use TkTextFont . If you rely on these defaults, you can change the fonts and all of the widgets will change accordingly. You can then either get the size of the display and pick the correct size before the UI is created, or you can set it up so that as the window is resized, the fonts change automatically.

To get a reference to a font you can use the nameToFont method from the font module. From there you can change any attribute of the font you want: family, size, etc. Here's a simple example of a function that sets the size of the default fonts based on the screen size:

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)

If you call this function before creating any widgets, they will all be created with the new size.

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

I have a suggestion.

instead of building a big and lengthy GUI which does all work in one screen, you can divide it in parts and make the GUI small. ( from 1000x800 to 600x400 i guess monitors cant be smmaler than this )

Like:

  1. Take customer details first in small GUI.
  2. then Vehicle details and so on

or:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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