如何在第二 monitor/display 上打开 Tkinter GUI? (Windows)
How to open Tkinter GUI on second monitor/display? (Windows)
我想加入一种方法,让我的 GUI 在第二台显示器上打开(如果可用)。我想添加某种类型的错误处理,因此如果有第二个显示器,请使用它,否则在检测到的显示器的中心打开。这能做到吗?
我一直在使用此代码段使用 win32 API 来枚举 windows 上的监视器:
import ctypes
user = ctypes.windll.user32
class RECT(ctypes.Structure):
_fields_ = [
('left', ctypes.c_long),
('top', ctypes.c_long),
('right', ctypes.c_long),
('bottom', ctypes.c_long)
]
def dump(self):
return [int(val) for val in (self.left, self.top, self.right, self.bottom)]
class MONITORINFO(ctypes.Structure):
_fields_ = [
('cbSize', ctypes.c_ulong),
('rcMonitor', RECT),
('rcWork', RECT),
('dwFlags', ctypes.c_ulong)
]
def get_monitors():
retval = []
CBFUNC = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_ulong, ctypes.c_ulong, ctypes.POINTER(RECT), ctypes.c_double)
def cb(hMonitor, hdcMonitor, lprcMonitor, dwData):
r = lprcMonitor.contents
#print("cb: %s %s %s %s %s %s %s %s" % (hMonitor, type(hMonitor), hdcMonitor, type(hdcMonitor), lprcMonitor, type(lprcMonitor), dwData, type(dwData)))
data = [hMonitor]
data.append(r.dump())
retval.append(data)
return 1
cbfunc = CBFUNC(cb)
temp = user.EnumDisplayMonitors(0, 0, cbfunc, 0)
#print(temp)
return retval
def monitor_areas():
retval = []
monitors = get_monitors()
for hMonitor, extents in monitors:
data = [hMonitor]
mi = MONITORINFO()
mi.cbSize = ctypes.sizeof(MONITORINFO)
mi.rcMonitor = RECT()
mi.rcWork = RECT()
res = user.GetMonitorInfoA(hMonitor, ctypes.byref(mi))
data = mi.rcMonitor.dump()
# data.append(mi.rcWork.dump())
retval.append(data)
return retval
if __name__ == "__main__":
print(monitor_areas())
在我的系统上打印
[[0, 0, 3440, 1440], [3440, 0, 5120, 1050]]
在 tkinter 中,您可以使用
将您的应用 window 移动到给定位置
appwindow.geometry('+1720+720')
它从左边 1720 像素,从顶部向下 720 像素。
位于主显示器左侧或上方的任何显示器可能会得到负坐标,但它们应该可以正常工作。
在 MacOS 上,使用 Appkit
:
import AppKit
[(screen.frame().size.width, screen.frame().size.height)
for screen in AppKit.NSScreen.screens()]
将为您提供包含所有屏幕尺寸的元组列表(如果存在多个显示器)
我想加入一种方法,让我的 GUI 在第二台显示器上打开(如果可用)。我想添加某种类型的错误处理,因此如果有第二个显示器,请使用它,否则在检测到的显示器的中心打开。这能做到吗?
我一直在使用此代码段使用 win32 API 来枚举 windows 上的监视器:
import ctypes
user = ctypes.windll.user32
class RECT(ctypes.Structure):
_fields_ = [
('left', ctypes.c_long),
('top', ctypes.c_long),
('right', ctypes.c_long),
('bottom', ctypes.c_long)
]
def dump(self):
return [int(val) for val in (self.left, self.top, self.right, self.bottom)]
class MONITORINFO(ctypes.Structure):
_fields_ = [
('cbSize', ctypes.c_ulong),
('rcMonitor', RECT),
('rcWork', RECT),
('dwFlags', ctypes.c_ulong)
]
def get_monitors():
retval = []
CBFUNC = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_ulong, ctypes.c_ulong, ctypes.POINTER(RECT), ctypes.c_double)
def cb(hMonitor, hdcMonitor, lprcMonitor, dwData):
r = lprcMonitor.contents
#print("cb: %s %s %s %s %s %s %s %s" % (hMonitor, type(hMonitor), hdcMonitor, type(hdcMonitor), lprcMonitor, type(lprcMonitor), dwData, type(dwData)))
data = [hMonitor]
data.append(r.dump())
retval.append(data)
return 1
cbfunc = CBFUNC(cb)
temp = user.EnumDisplayMonitors(0, 0, cbfunc, 0)
#print(temp)
return retval
def monitor_areas():
retval = []
monitors = get_monitors()
for hMonitor, extents in monitors:
data = [hMonitor]
mi = MONITORINFO()
mi.cbSize = ctypes.sizeof(MONITORINFO)
mi.rcMonitor = RECT()
mi.rcWork = RECT()
res = user.GetMonitorInfoA(hMonitor, ctypes.byref(mi))
data = mi.rcMonitor.dump()
# data.append(mi.rcWork.dump())
retval.append(data)
return retval
if __name__ == "__main__":
print(monitor_areas())
在我的系统上打印 [[0, 0, 3440, 1440], [3440, 0, 5120, 1050]]
在 tkinter 中,您可以使用
将您的应用 window 移动到给定位置appwindow.geometry('+1720+720')
它从左边 1720 像素,从顶部向下 720 像素。
位于主显示器左侧或上方的任何显示器可能会得到负坐标,但它们应该可以正常工作。
在 MacOS 上,使用 Appkit
:
import AppKit
[(screen.frame().size.width, screen.frame().size.height)
for screen in AppKit.NSScreen.screens()]
将为您提供包含所有屏幕尺寸的元组列表(如果存在多个显示器)