removed scaling with ctypes shcore for Windows < 8.1

This commit is contained in:
Tom Schimansky 2022-05-26 19:16:01 +02:00
parent 34da9505e9
commit a1afc3056b
6 changed files with 45 additions and 32 deletions

View File

@ -22,6 +22,9 @@ if sys.platform == "darwin":
else:
DrawEngine.preferred_drawing_method = "font_shapes"
if sys.platform.startswith("win") and sys.getwindowsversion().build < 9000: # No automatic scaling on Windows < 8.1
ScalingTracker.deactivate_automatic_dpi_awareness = True
# load Roboto fonts (used on Windows/Linux)
script_directory = os.path.dirname(os.path.abspath(__file__))
FontManager.load_font(os.path.join(script_directory, "assets", "fonts", "Roboto", "Roboto-Regular.ttf"))

View File

@ -124,7 +124,7 @@ class ScalingTracker:
@classmethod
def activate_high_dpi_awareness(cls):
""" make process DPI aware, customtkinter elemets will get scaled automatically,
""" make process DPI aware, customtkinter elements will get scaled automatically,
only gets activated when CTk object is created """
if not cls.deactivate_automatic_dpi_awareness:
@ -135,28 +135,30 @@ class ScalingTracker:
from ctypes import windll
windll.shcore.SetProcessDpiAwareness(2)
# Microsoft Docs: https://docs.microsoft.com/en-us/windows/win32/api/shellscalingapi/ne-shellscalingapi-process_dpi_awareness
else:
pass # DPI awareness on Linux not implemented
@classmethod
def get_window_dpi_scaling(cls, window) -> float:
if sys.platform == "darwin":
return 1 # scaling works automatically on macOS
if not cls.deactivate_automatic_dpi_awareness:
if sys.platform == "darwin":
return 1 # scaling works automatically on macOS
elif sys.platform.startswith("win"):
from ctypes import windll, pointer, wintypes
elif sys.platform.startswith("win"):
from ctypes import windll, pointer, wintypes
DPI100pc = 96 # DPI 96 is 100% scaling
DPI_type = 0 # MDT_EFFECTIVE_DPI = 0, MDT_ANGULAR_DPI = 1, MDT_RAW_DPI = 2
window_hwnd = wintypes.HWND(window.winfo_id())
monitor_handle = windll.user32.MonitorFromWindow(window_hwnd, wintypes.DWORD(2)) # MONITOR_DEFAULTTONEAREST = 2
x_dpi, y_dpi = wintypes.UINT(), wintypes.UINT()
windll.shcore.GetDpiForMonitor(monitor_handle, DPI_type, pointer(x_dpi), pointer(y_dpi))
return (x_dpi.value + y_dpi.value) / (2 * DPI100pc)
DPI100pc = 96 # DPI 96 is 100% scaling
DPI_type = 0 # MDT_EFFECTIVE_DPI = 0, MDT_ANGULAR_DPI = 1, MDT_RAW_DPI = 2
window_hwnd = wintypes.HWND(window.winfo_id())
monitor_handle = windll.user32.MonitorFromWindow(window_hwnd, wintypes.DWORD(2)) # MONITOR_DEFAULTTONEAREST = 2
x_dpi, y_dpi = wintypes.UINT(), wintypes.UINT()
windll.shcore.GetDpiForMonitor(monitor_handle, DPI_type, pointer(x_dpi), pointer(y_dpi))
return (x_dpi.value + y_dpi.value) / (2 * DPI100pc)
else:
return 1 # DPI awareness on Linux not implemented
else:
return 1 # DPI awareness on Linux not implemented
return 1
@classmethod
def check_dpi_scaling(cls):

View File

@ -93,7 +93,7 @@ class CTkOptionMenu(CTkBaseClass):
height=self.apply_widget_scaling(self.desired_height))
self.draw()
def set_dimensions(self, width=None, height=None):
def set_dimensions(self, width: int = None, height: int = None):
super().set_dimensions(width, height)
self.canvas.configure(width=self.apply_widget_scaling(self.desired_width),
@ -148,10 +148,9 @@ class CTkOptionMenu(CTkBaseClass):
y_position=self.winfo_rooty() + self.current_height + 4,
width=self.current_width,
values=self.values,
command=self.set_value)
command=self.set)
def set_value(self, value):
print("set value", value)
def set(self, value: str):
self.current_value = value
if self.text_label is not None:
@ -159,6 +158,9 @@ class CTkOptionMenu(CTkBaseClass):
else:
self.draw()
def get(self) -> str:
return self.current_value
def configure(self, *args, **kwargs):
require_redraw = False # some attribute changes require a call of self.draw() at the end
@ -181,10 +183,15 @@ class CTkOptionMenu(CTkBaseClass):
require_redraw = True
del kwargs["bg_color"]
if "hover_color" in kwargs:
self.hover_color = kwargs["hover_color"]
if "button_color" in kwargs:
self.button_color = kwargs["button_color"]
require_redraw = True
del kwargs["hover_color"]
del kwargs["button_color"]
if "button_hover_color" in kwargs:
self.button_hover_color = kwargs["button_hover_color"]
require_redraw = True
del kwargs["button_hover_color"]
if "text_color" in kwargs:
self.text_color = kwargs["text_color"]
@ -252,10 +259,10 @@ class CTkOptionMenu(CTkBaseClass):
if self.state is not tkinter.DISABLED:
self.open_dropdown_menu()
if self.function is not None:
# click animation: change color with .on_leave() and back to normal after 100ms with click_animation()
self.on_leave()
self.click_animation_running = True
self.after(100, self.click_animation)
# click animation: change color with .on_leave() and back to normal after 100ms with click_animation()
self.on_leave()
self.click_animation_running = True
self.after(100, self.click_animation)
if self.function is not None:
self.function()

View File

@ -58,7 +58,4 @@ s_var = tkinter.StringVar(value="on")
switch_1 = customtkinter.CTkSwitch(master=frame_1)
switch_1.pack(pady=y_padding, padx=10)
optionmenu_1 = customtkinter.CTkOptionMenu(master=frame_1, values=["option 1", "option 2", "number 42"])
optionmenu_1.pack(pady=y_padding, padx=10)
app.mainloop()

View File

@ -2,7 +2,7 @@
name = customtkinter
version = 4.1.0
description = Create modern looking GUIs with Python
long_description = file: README.md
long_description = file: Readme.md
long_description_content_type = text/markdown
url = https://github.com/TomSchimansky/CustomTkinter
author = Tom Schimansky

View File

@ -1,4 +1,5 @@
from tkinter import *
import customtkinter
ws = Tk()
ws.title('PythonGuides')
@ -13,7 +14,7 @@ countries = ['Bahamas','Canada', 'Cuba','United States']
# setting variable for Integers
variable = StringVar()
variable.set(countries[3])
variable.set("test")
# creating widget
dropdown = OptionMenu(
@ -24,7 +25,10 @@ dropdown = OptionMenu(
)
# positioning widget
dropdown.pack(expand=True)
dropdown.pack(pady=10, padx=10)
optionmenu_1 = customtkinter.CTkOptionMenu(master=ws, values=["option 1", "option 2", "number 42"])
optionmenu_1.pack(pady=10, padx=10)
# infinite loop
ws.mainloop()