如何在 wxPython 中获取具有不同 DPI 和分辨率的小部件/字体大小?

K-D*_*Doe 5 python user-interface wxpython dpi python-3.x

我用 wxPython 编写了一个程序。我们在许多具有不同显示配置的不同计算机上运行该程序。

例子:

  • 1920x1080,DPI 100%

  • 3000x2000,DPI 175%

  • 1980x1080,DPI 150%(小型 13" 显示笔记本电脑)

我在全高清、DPI 100% 显示器上编码 - GUI 看起来不错!特别是在 3000x2000 上。TextCtrls、BitmapButtons 和Images 通常会改变它们的大小(它们变得更小)并且GUI 因不同的分辨率而变得混乱。DPI 150% 相同。

我试图通过在我的主类中设置我的进程的 DPI 意识来防止它,但这并不能始终如一地工作。

以下是我设置 DPI 意识的方式:

import ctypes

# Query DPI Awareness (Windows 10 and 8)
awareness = ctypes.c_int()
errorCode = ctypes.windll.shcore.GetProcessDpiAwareness(0, ctypes.byref(awareness))

# Set DPI Awareness  (Windows 10 and 8)
errorCode = ctypes.windll.shcore.SetProcessDpiAwareness(2)
Run Code Online (Sandbox Code Playgroud)

题:

  1. 我需要做什么才能使我的 GUI 在所有 DPI 和分辨率设置上看起来至少相似?
  2. 使用图像有什么特别的考虑吗?
  3. 我是否需要直接在我的代码中缩放小部件/字体大小?
  4. 在sizer中设置小部件的大小和距离有什么提示吗?

我将附上一个代码示例,其中我尝试尽可能多地进行大小和定位,以便为你们提供可能修复某些问题的基础。

import wx
import wx.adv


class Mywin(wx.Frame):
    def __init__(self,parent,title):
        wx.Frame.__init__(self, parent, wx.ID_ANY, title,size= (600,-1))
        
        self.SetSize(800,500)

        sizer_1 = wx.BoxSizer(wx.VERTICAL)        
        sizer_1.Add(wx.StaticText(self, size=(125,-1), label='Order ID'), 0, wx.ALL , 5)
        sizer_1.Add(wx.StaticText(self, size=(125,-1), label='Status'), 0, wx.ALL , 5)
        sizer_1.Add(wx.StaticText(self, size=(125,-1), label='Creator'), 0, wx.ALL , 5)
        sizer_1.Add((-1, 5))
        sizer_1.Add(wx.StaticText(self, size=(125,-1), label='Comment'), 0, wx.ALL , 5)
        sizer_1.Add((-1, 40))
        sizer_1.Add(wx.StaticText(self, size=(125,-1), label='Customer ID'), 0, wx.ALL , 5)
        sizer_1.Add(wx.StaticText(self, size=(125,-1), label='Customer Name'), 0, wx.ALL , 5)        
        sizer_1.Add(wx.StaticText(self, size=(125,-1), label='Contact Person'), 0, wx.ALL , 5)
        sizer_1.Add((-1, 21))
        sizer_1.Add(wx.StaticText(self, size=(125,-1), label='Inquiry Date'), 0, wx.ALL , 5)


        ctrl_height = 25
        stati = ["Test", "Example"]
        
        tc_order_id = wx.TextCtrl(self, -1, size=(100, ctrl_height),style=wx.TE_PROCESS_ENTER)
        cb_status = wx.ComboBox(self,size=(100, ctrl_height), choices=stati, style=wx.CB_READONLY)        
        cb_creator = wx.ComboBox(self,size=(100, ctrl_height), choices=stati, style=wx.CB_READONLY)
        tc_comment = wx.TextCtrl(self, id=-1, value='', size=(300,55), style=wx.TE_MULTILINE|wx.SUNKEN_BORDER)        
        tc_customer_id = wx.TextCtrl(self, -1, size=(80, ctrl_height),style=wx.TE_PROCESS_ENTER)                             
        tc_customer_name = wx.TextCtrl(self, -1, size=(300, ctrl_height),style=wx.TE_READONLY)        
        tc_contact_id = wx.TextCtrl(self, -1, size=(80, ctrl_height),style=wx.TE_PROCESS_ENTER)
        
        calender_style = wx.adv.DP_DROPDOWN | wx.adv.DP_SHOWCENTURY | wx.adv.DP_ALLOWNONE
        tc_order_date = wx.adv.GenericDatePickerCtrl(self, size=(90,ctrl_height), style = calender_style)
        
        sizer_2 = wx.BoxSizer(wx.VERTICAL)
        sizer_2.Add(tc_order_id, 0)
        sizer_2.Add(cb_status,0, wx.TOP , 3)
        sizer_2.Add(cb_creator, wx.TOP , 2)
        sizer_2.Add(tc_comment, 0, wx.TOP, 9)
        sizer_2.Add(tc_customer_id, 0, wx.TOP, 4)
        sizer_2.Add(tc_customer_name, 0, wx.TOP, 4)
        sizer_2.Add(tc_contact_id, 0, wx.TOP, 4)
        sizer_2.Add(tc_order_date, 0, wx.TOP, 20)
        
        mainsizer = wx.BoxSizer(wx.HORIZONTAL)
        mainsizer.Add(sizer_1)
        mainsizer.Add(sizer_2)
        
        self.SetSizer(mainsizer)
        
        self.Centre()
        self.Show()
        self.Layout()


demo = wx.App()
Mywin(None,'Example Code')
demo.MainLoop()
Run Code Online (Sandbox Code Playgroud)