I have a very specific issue that I have been trying to sort out for some time now. I am using Python 2.7 in Pycharm on Mac. I am working on a touchscreen GUI to interface with a robot. The issue that I am having is that I am trying to make this GUI look as similar as possible on multiple platforms and on different display sizes as far as button and label sizing goes.
What I tried doing is using python to detect the display resolution and from that, base the elements/widgets sizes as ratios of the resolution. This has worked just fine when using my MacBook Pro Retina 15" with a resolution of 1440x900 as well as a Raspberry Pi with resolution set to 1280x800 however when I attempt to do this on a PC with a resolution of 1920x1080, it somehow detects the height to be 1135 instead of 1080. I have two frames created self.f1 and self.f2 which is placed centered in self.f1 and what is interesting is that in my GUI on Windows, somehow the height of self.f2 is larger than the height of self.f1 which I think may be a part of my issue. Here is the specific code for the GUI portion of my program:
def gui_layout(self):
x_default = .5
y_default = .52
if self.version[1] == "1":
x_off = x_default
y_off = .535
elif self.version[1] == "2":
x_off = x_default
y_off = y_default
else:
x_off = x_default
y_off = y_default
# GUI framework initialization
self.title("Operator Interface - " + self.version)
self.w_0, self.h_0 = self.winfo_screenwidth(), self.winfo_screenheight()
self.geometry("%dx%d+0+0" % (self.w_0, self.h_0))
# self.overrideredirect(True)
self.wm_attributes('-fullscreen', 'True')
self.f1 = tk.Frame(width=self.w_0, height=self.h_0, bg="white")
self.f2 = tk.Frame(bg="black")
self.f1.pack(fill="both", expand=True)
self.f2.place(in_=self.f1, anchor="c", relx=x_off, rely=y_off)
# Create status bar objects
if self.version[1] == "2":
self.state_text = " Status: %s |" % self.status.mission_text
self.state_bar = tk.Label(self.f1, text=self.state_text, bd=1, relief='sunken', anchor='w',
font=("Helvetica", 20))
self.state_bar.pack(side='bottom', fill='x')
else:
pass
self.status_text = " State: %s | Current Mission: %s | Battery: %s" % (
self.status.state_text, "Mission Name", self.status.battery_percentage) + "%" + "(%ss) | Network: %s" % (
self.status.battery_time, "Network Status")
self.status_bar = tk.Label(self.f1, text=self.status_text, bd=1, relief='sunken', anchor='w',
font=("Helvetica", 20))
self.status_bar.pack(side='bottom', fill='x')
self.orig_color = self.status_bar.cget("background")
self.image_0 = Image.open("%s/Images/MIR.bmp" % self.folder_path)
self.photo_0 = ImageTk.PhotoImage(self.image_0)
self.image_0_label = tk.Label(self.f1, image=self.photo_0)
self.image_0_label.image = self.photo_0
self.w = self.w_0 / 70
self.h = self.h_0 / 90
self.w_1 = self.w_0 / 96
self.h_1 = self.h_0 / 450
self.button_1 = tk.Button(self.f2, text="Button 1", command=lambda: self.dummy_method(),
font=("Helvetica", 20), width=self.w, height=self.h)
self.button_2 = tk.Button(self.f2, text="Button 2", command=lambda: self.dummy_method(),
font=("Helvetica", 20), width=self.w, height=self.h)
self.button_3 = tk.Button(self.f2, text="Button 3", command=lambda: self.dummy_method(),
font=("Helvetica", 20), width=self.w, height=self.h)
self.button_4 = tk.Button(self.f2, text="Button 4", command=lambda: self.dummy_method(),
font=("Helvetica", 20), width=self.w, height=self.h)
self.button_5 = tk.Button(self.f2, text="Button 5", command=lambda: self.dummy_method(),
font=("Helvetica", 20), width=self.w, height=self.h)
self.button_6 = tk.Button(self.f2, text="Button 6", command=lambda: self.dummy_method(),
font=("Helvetica", 20), width=self.w, height=self.h)
self.button_7 = tk.Button(self.f2, text="Button 7", command=lambda: self.dummy_method(),
font=("Helvetica", 20), width=self.w_1, height=self.h_1)
self.button_8 = tk.Button(self.f2, text="Button 8", command=lambda: self.dummy_method(),
font=("Helvetica", 20), width=self.w_1, height=self.h_1)
self.button_9 = tk.Button(self.f2, text="Button 9", command=lambda: self.help(), font=("Helvetica", 20),
width=self.w_1, height=self.h_1)
self.image_0_label.pack(fill='x')
self.button_1.grid(row=2, column=2, padx=20, pady=10)
self.button_2.grid(row=2, column=3, padx=20, pady=10)
self.button_3.grid(row=2, column=4, padx=20, pady=10)
self.button_4.grid(row=3, column=2, padx=20, pady=10)
self.button_5.grid(row=3, column=3, padx=20, pady=10)
self.button_6.grid(row=3, column=4, padx=20, pady=10)
self.button_7.grid(row=4, column=2, padx=20, pady=10)
self.button_8.grid(row=4, column=3, padx=20, pady=10)
self.button_9.grid(row=4, column=4, padx=20, pady=10)
self.button_configure()
Also here are the values that I get when running different resolution retrieving commands on the Pi (1st image) and Windows (2nd image).
If anyone has any suggestions or guidance on how I can make this GUI look like this on any screen size, that would be much appreciated. The window itself will not be resized once booted but I just would like it to go full screen and the buttons to size nicely.
Here, try this:
import tkinter as tk
root = tk.Tk()
# set columns 0, 1 and 2 and rows 0 and 1 to expand to the full possible size
root.columnconfigure(0, weight=1)
root.columnconfigure(1, weight=1)
root.columnconfigure(2, weight=1)
root.rowconfigure(0, weight=1)
root.rowconfigure(1, weight=1)
# row zero
btn = tk.Button(root, text="Call")
btn.grid(row=0, column=0, sticky='nsew', padx=5, pady=5)
btn = tk.Button(root, text="Send to Sawyer")
btn.grid(row=0, column=1, sticky='nsew', padx=5, pady=5)
btn = tk.Button(root, text="Send to Compressor")
btn.grid(row=0, column=2, sticky='nsew', padx=5, pady=5)
# row one
btn = tk.Button(root, text="Send to Loading Dock")
btn.grid(row=1, column=0, sticky='nsew', padx=5, pady=5)
btn = tk.Button(root, text="Send to Charging Dock")
btn.grid(row=1, column=1, sticky='nsew', padx=5, pady=5)
btn = tk.Button(root, text="MiR is on the Way")
btn.grid(row=1, column=2, sticky='nsew', padx=5, pady=5)
# row two
btn = tk.Button(root, text="Supervisor")
btn.grid(row=2, column=0, sticky='nsew', padx=5, pady=5)
btn = tk.Button(root, text="Setup")
btn.grid(row=2, column=1, sticky='nsew', padx=5, pady=5)
btn = tk.Button(root, text="Help")
btn.grid(row=2, column=2, sticky='nsew', padx=5, pady=5)
# row three
state_bar = tk.Label(root, text = " State: %s | Current Mission: %s | Battery: %s")
state_bar.grid(row=3, column=0, columnspan=3)
try:
root.state('zoomed') # windows
except:
root.attributes('-zoomed', True) # linux
root.mainloop()
Resize it and see how tkinter handles sizing everything automatically.