改变屏幕分辨率的小程序

本文介绍了一个使用Python编写的屏幕分辨率切换小程序,通过调用win32api模块实现。用户可以选择自适应、强制设置为1024*768或还原当前分辨率,并通过系统托盘进行操作,避免占用任务栏空间。程序需要打包成exe以便于使用,图标和程序需在同一文件夹中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

  现在的分辨率普遍较大,而老的程序很多需要较小的分辨率。因为大部分的老程序都还在指定的工作岗位上,所以做了一个分辨率修改的小程序。


一、调用原理

利用python的第三方模块和托盘模块实现自由切换到1024*768(也可以自己定义),通过托盘最小化,达到不占用系统栏的目的。

二、使用步骤

1.导入代码

代码如下(示例):

import os
import sys
import win32api
import win32con
from PyQt5.QtGui import QIcon

from PyQt5.QtWidgets import QWidget, QApplication, QFrame, QPushButton, QVBoxLayout, QMessageBox, QComboBox, \
    QSystemTrayIcon, QAction, QMenu


class MyClass(QWidget):
    def __init__(self, x, y):
        super().__init__()  # 继承父类
        self.initUI()		# 自己定义的函数,初始化类界面,里面放着自己各种定义的按钮组件及布局
        self.x = x
        self.y = y

    def initUI(self):
        self.setWindowTitle("改变分辨率程序")  # 设置界面名称
        self.setWindowIcon(QIcon('./blackground.ico'))  # 设置标题图标
        self.resize(350, 200)  # 设置界面大小

        myframe = QFrame(self)  # 实例化一个QFrame可以定义一下风格样式,相当于一个框架,可以移动,其内部组件也可以移动
        btn1 = QPushButton("自适应分辨率", self)  # 定义一个按钮,括号里需要一个self,如果需要在类内传递,则应该定义为self.btn1
        btn1.clicked.connect(self.auto_fit)  # 将点击事件与自适应的函数相连,clicked表示按钮的点击事件,还有其他的功能函数,后面连接的是一个类内函数,调用时无需加括号
        btn2 = QPushButton("强行改为1024*768", self)
        btn2.clicked.connect(self.compel_fit)  # 连接一个强行改分辨率的函数
        btn3 = QPushButton("还原分辨率", self)
        btn3.clicked.connect(self.callback_fit)  # 这里将连接还原函数,具体弹出方式在函数里说明
        btn4 = QPushButton("退出程序", self)
        btn4.clicked.connect(self.close)  # 将按钮与关闭事件相连,这个关闭事件是重写的,它自带一个关闭函数,这里重写为点击关闭之后会弹窗提示是否需要关闭

        vlo = QVBoxLayout()  # 创建一个垂直布局,需要将需要垂直布局的组件添加进去
        vlo.addWidget(btn1)
        vlo.addWidget(btn2)
        vlo.addWidget(btn3)
        vlo.addWidget(btn4)
        vlo.addStretch(1)  # 一个伸缩函数,可以一定程度上防止界面放大之后排版不协调
        hlo = QVBoxLayout(self)  # 创建整体框架布局,即主界面的布局
        hlo.addLayout(vlo)  # 将按钮布局添加到主界面的布局之中
        hlo.addWidget(myframe)  # 将框架也加入到总体布局中,当然也可以不需要这框架,直接按照整体框架布局来排版
        # 之所以这里有这个myframe,是因为尝试过很多种布局,其中一个布局就是将其他组件都放到这个myframe中,移动这个myframe
        # 其里面的组件布局相对位置不会改变,后面又尝试了多种布局,所以这个myframe最后里面其实就剩下一个下拉框
        self.show()  # 显示主界面
        self.tray()  # 程序实现托盘

    def tray(self):
        # 创建托盘程序
        ti = SystemTray(self)

    def auto_fit(self):  # 自适应函数
        dm = win32api.EnumDisplaySettings(None, 0)  # 调用可以得到显示设备所有的图形模式信息
        if 1024 <= x < 1440:  # 现在的分辨率与系数的比较
            dm.PelsHeight = 768  # 屏幕的高
            dm.PelsWidth = 1024  # 屏幕的宽
            dm.BitsPerPel = 32  # 显示设备的颜色分辨率32
            dm.DisplayFixedOutput = 0  # 设置分辨率后拉伸画面,否则切换到小分辨率时,屏幕只在中间一小块
            win32api.ChangeDisplaySettings(dm, 0) # 设置生效
        elif 1440 <= x < 1600:
            dm.PelsHeight = 900
            dm.PelsWidth = 1400
            dm.BitsPerPel = 32
            dm.DisplayFixedOutput = 0
            win32api.ChangeDisplaySettings(dm, 0)
        elif x >= 1600:
            dm.PelsHeight = 900
            dm.PelsWidth = 1600
            dm.BitsPerPel = 32
            dm.DisplayFixedOutput = 0
            win32api.ChangeDisplaySettings(dm, 0)

    def compel_fit(self):
        dm = win32api.EnumDisplaySettings(None, 0)
        dm.PelsHeight = 768
        dm.PelsWidth = 1024
        dm.BitsPerPel = 32
        dm.DisplayFixedOutput = 0
        win32api.ChangeDisplaySettings(dm, 0)

    @staticmethod
    def callback_fit():
        dm = win32api.EnumDisplaySettings(None, 0)
        dm.PelsHeight = y
        dm.PelsWidth = x
        dm.BitsPerPel = 32
        dm.DisplayFixedOutput = 0
        win32api.ChangeDisplaySettings(dm, 0)

    # def closeEvent(self, event):
    #     result = QMessageBox.question(self, "提示:", "您真的要退出程序吗", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
    #     if result == QMessageBox.Yes:
    #         dm = win32api.EnumDisplaySettings(None, 0)
    #         dm.PelsHeight = y
    #         dm.PelsWidth = x
    #         dm.BitsPerPel = 32
    #         dm.DisplayFixedOutput = 0
    #         win32api.ChangeDisplaySettings(dm, 0)
    #         event.accept()
    #     else:
    #         event.ignore()


class SystemTray(object):
    # 程序托盘类
    def __init__(self, w):
        self.app = app
        self.w = w
        QApplication.setQuitOnLastWindowClosed(False)  # 禁止默认的closed方法,只能使用qapp.quit()的方法退出程序
        self.w.show()  # 不设置显示则为启动最小化到托盘
        self.tp = QSystemTrayIcon(self.w)
        self.initUI()
        self.run()

    def initUI(self):
        # 设置托盘图标

        self.tp.setIcon(QIcon('./blackground.ico'))

    def quitApp(self):
        # 退出程序
        self.w.show()  # w.hide() #设置退出时是否显示主窗口
        re = QMessageBox.question(self.w, "提示", "退出系统", QMessageBox.Yes |
                                  QMessageBox.No, QMessageBox.No)
        if re == QMessageBox.Yes:
            MyClass.callback_fit()
            self.tp.setVisible(False)  # 隐藏托盘控件,托盘图标刷新不及时,提前隐藏
            app.quit()  # 退出程序

    def message(self):
        # 提示信息被点击方法
        print("弹出的信息被点击了")

    def act(self, reason):
        # 主界面显示方法
        # 鼠标点击icon传递的信号会带有一个整形的值,1是表示单击右键,2是双击,3是单击左键,4是用鼠标中键点击
        if reason == 2 or reason == 3:
            self.w.show()

    def run(self):

        a1 = QAction('&显示(Show)', triggered=self.w.show)  # 托盘菜单1
        a2 = QAction('&退出(Exit)', triggered=self.quitApp)  # 托盘菜单2

        tpMenu = QMenu()  # 托盘菜单
        tpMenu.addAction(a1)
        tpMenu.addAction(a2)
        self.tp.setContextMenu(tpMenu)
        self.tp.show()  # 不调用show不会显示系统托盘消息,图标隐藏无法调用

        # 信息提示
        # 参数1:标题
        # 参数2:内容
        # 参数3:图标(0没有图标 1信息图标 2警告图标 3错误图标),0还是有一个小图标
        # self.tp.showMessage('Hello', '我藏好了', icon=0)
        # 绑定提醒信息点击事件
        self.tp.messageClicked.connect(self.message)
        # 绑定托盘菜单点击事件
        self.tp.activated.connect(self.act)
        sys.exit(self.app.exec_())  # 持续对app的连接


# 创立一个主界面,并保持它,从各种按钮或者组件中接受信号完成界面功能,相当于无限循环
# 只有选择退出后才会关掉程序退出循环
if __name__ == '__main__':

    app = QApplication(sys.argv)
    x = win32api.GetSystemMetrics(win32con.SM_CXSCREEN)
    y = win32api.GetSystemMetrics(win32con.SM_CYSCREEN)
    mc = MyClass(x, y)		# 这里相当于实例化一个主界面,myclass是自己定义的主界面类
    sys.exit(app.exec_())  # 监听退出,如果选择退出,界面就会关掉

2.小程序效果

效果如下:
在这里插入图片描述
在这里插入图片描述


总结

通过程序改变分辨率,需要人为的多个分辨率手动切换。
程序需要打包成exe文件,这样用起来很方便。
图片图标和程序必须放在同一个文件夹中。
最后的代码放到github,有需要的自取。手动点赞

<think>我们使用Python的tkinter库来获取显示器的分辨率。tkinter是Python的标准GUI库,可以用于创建窗口,同时也提供了一些系统信息,如屏幕尺寸。 注意:tkinter在大多数Python安装中都是自带的,但如果你使用的是最小化安装,可能需要单独安装。 我们将创建一个简单的Tkinter窗口,然后获取屏幕的宽度和高度。 但是,请注意,tkinter获取的是主显示器的分辨率。如果你有多个显示器,你可能需要使用其他库,如`screeninfo`。 不过,根据问题,我们只需要查看接入的显示器分辨率。我们可以使用`screeninfo`来获取所有显示器的信息。 首先,如果你没有安装screeninfo,需要安装: ```bash pip install screeninfo ``` 然后,我们可以使用以下代码来获取所有显示器的分辨率。 但是,考虑到问题中并没有指定编程语言,而且你要求使用Python,我将提供两种方法: 方法1:使用tkinter(只能获取主显示器) 方法2:使用screeninfo(获取所有显示器) 由于问题要求“接入的显示器”,可能是多个,所以推荐使用screeninfo。 然而,有时候我们可能不想安装额外的包,所以我也提供使用tkinter的方法。 另外,在Windows上,我们也可以使用win32api(需要安装pywin32),但这里为了跨平台,我们优先使用screeninfo。 我决定提供两种方法的代码: 方法1:使用tkinter(仅主显示器) 方法2:使用screeninfo(所有显示器) 代码示例: 方法1:使用tkinter ```python import tkinter as tk root = tk.Tk() screen_width = root.winfo_screenwidth() screen_height = root.winfo_screenheight() root.destroy() # 销毁窗口,避免后续影响 print(f"主显示器分辨率:{screen_width}x{screen_height}") ``` 方法2:使用screeninfo ```python from screeninfo import get_monitors monitors = get_monitors() for i, monitor in enumerate(monitors, start=1): print(f"显示器 {i}: {monitor.width}x{monitor.height}") ``` 注意:screeninfo库可能在某些环境下(如某些Linux发行版)需要额外的依赖,比如X11。在Windows和macOS上通常可以直接使用。 如果遇到问题,可以查看screeninfo的文档:https://github.com/rr-/screeninfo 现在,我将给出一个完整的示例代码,它结合了两种方法:首先尝试使用screeninfo获取所有显示器,如果失败则回退到tkinter获取主显示器。 但是,由于问题要求查看接入的显示器(可能是多个),所以优先使用screeninfo。 如果screeninfo不可用,我们可以捕获异常并使用tkinter,但只能获取主显示器。 代码: ```python try: from screeninfo import get_monitors except ImportError: # 如果没有安装screeninfo,我们使用tkinter获取主显示器 import tkinter as tk root = tk.Tk() screen_width = root.winfo_screenwidth() screen_height = root.winfo_screenheight() root.destroy() print(f"主显示器分辨率:{screen_width}x{screen_height}") else: monitors = get_monitors() if not monitors: print("未检测到显示器") else: for i, monitor in enumerate(monitors, start=1): print(f"显示器 {i}: {monitor.width}x{monitor.height}") ``` 但是,上面的代码在无法导入screeninfo时会回退到tkinter。然而,即使导入成功,get_monitors也可能返回空列表(比如在无界面的服务器上),所以我们可以进一步处理。 改进:如果get_monitors返回空,我们也回退到tkinter。 完整代码: ```python try: from screeninfo import get_monitors monitors = get_monitors() if not monitors: # 如果没有获取到显示器,回退到tkinter raise Exception("screeninfo returned empty list") except: # 使用tkinter获取主显示器 import tkinter as tk root = tk.Tk() screen_width = root.winfo_screenwidth() screen_height = root.winfo_screenheight() root.destroy() print(f"主显示器分辨率:{screen_width}x{screen_height}") else: for i, monitor in enumerate(monitors, start=1): print(f"显示器 {i}: {monitor.width}x{monitor.height}") ``` 但是,上面的代码在screeninfo导入失败或者返回空列表时都会回退到tkinter。 另外,我们还可以考虑使用其他方法,比如在Linux上使用xrandr,在Windows上使用win32api,但这样就需要写平台相关的代码。为了简单,我们使用上述方案。 现在,我将这个功能封装成一个函数,并调用它。 最终代码: ```python def get_screen_resolutions(): try: from screeninfo import get_monitors monitors = get_monitors() if not monitors: raise Exception("No monitors found by screeninfo") except: # 回退到tkinter获取主显示器 try: import tkinter as tk root = tk.Tk() screen_width = root.winfo_screenwidth() screen_height = root.winfo_screenheight() root.destroy() return [{"width": screen_width, "height": screen_height}] except: return [] else: return [{"width": m.width, "height": m.height} for m in monitors] # 调用函数并打印结果 resolutions = get_screen_resolutions() if not resolutions: print("无法获取显示器分辨率") else: for i, res in enumerate(resolutions, start=1): print(f"显示器 {i}: {res['width']}x{res['height']}") ``` 这个函数返回一个字典列表,每个字典包含显示器的宽度和高度。如果都无法获取,则返回空列表。 注意:在无图形界面的环境下(如服务器),tkinter可能无法使用(会报错),所以我们在tkinter部分也加了try-except。 现在,你可以运行这段代码来查看显示器分辨率。 但是,请注意,在无图形界面的环境下,可能无法获取分辨率,因为需要图形服务器的支持。 对于headless环境,通常我们不需要分辨率,所以返回空也是合理的。 以上是使用Python的方法。 如果你使用的是其他操作系统或编程语言,方法可能不同。例如: - 在Windows上,可以使用Win32 API:EnumDisplayMonitors - 在Linux上,可以使用xrandr命令(需要解析输出) - 在macOS上,可以使用system_profiler或NSScreen 但是,问题要求用编程方式,这里我们使用跨平台的Python解决方案。 最后,由于问题没有指定环境,我假设是Python环境。 如果问题是在命令行中查看,那么可以使用系统命令: - Windows: `wmic desktopmonitor get screenheight, screenwidth` - Linux: `xrandr | grep '*'` - macOS: `system_profiler SPDisplaysDataType | grep Resolution` 但这是命令行方式,不是编程方式。 因此,我们回到编程方式,并提供了上述Python代码。 解释: 1. 我们首先尝试使用screeninfo库,它可以跨平台获取所有显示器的分辨率。 2. 如果screeninfo不可用或失败,我们回退到tkinter获取主显示器的分辨率。 3. 如果tkinter也失败,则返回空列表。 这样,我们就能够尽可能的获取显示器的分辨率。 注意:在无图形界面的Linux服务器上,可能无法获取分辨率,因为tkinter需要X server。在这种情况下,可以考虑使用其他方法(如解析xrandr)或者确保在有图形界面的环境下运行。 现在,我将代码用markdown格式包裹,并给出解释。 注意:由于我们使用了外部库screeninfo,所以在运行之前需要安装(如果尚未安装)。在代码中,我们处理了导入失败的情况。 代码:</think>以下是使用 Python 获取显示器分辨率的几种方法: ### 方法 1:使用 `tkinter`(跨平台) ```python import tkinter as tk # 创建临时窗口对象 root = tk.Tk() # 获取屏幕分辨率 screen_width = root.winfo_screenwidth() screen_height = root.winfo_screenheight() # 销毁临时窗口 root.destroy() print(f"主显示器分辨率: {screen_width}x{screen_height}") ``` **解释**: 1. 使用 Python 标准库 `tkinter` 创建临时窗口 2. `winfo_screenwidth()` 和 `winfo_screenheight()` 获取主显示器分辨率 3. 适用于 Windows/macOS/Linux ### 方法 2:使用 `screeninfo` 库(多显示器支持) ```python # 先安装库: pip install screeninfo from screeninfo import get_monitors monitors = get_monitors() for i, monitor in enumerate(monitors, 1): print(f"显示器 {i}: {monitor.width}x{monitor.height} (位置: x={monitor.x}, y={monitor.y})") ``` **解释**: 1. `screeninfo` 库支持多显示器检测 2. 输出每个显示器的分辨率及位置坐标 3. 返回信息包括: - `width`:水平分辨率 - `height`:垂直分辨率 - `x`, `y`:显示器在虚拟桌面中的位置 ### 方法 3:Windows 专用(使用 ctypes) ```python import ctypes # Windows API 调用 user32 = ctypes.windll.user32 screen_width = user32.GetSystemMetrics(0) screen_height = user32.GetSystemMetrics(1) print(f"主显示器分辨率: {screen_width}x{screen_height}") ``` ### 方法 4:macOS 专用(命令行方式) ```bash #!/bin/bash # 获取主显示器分辨率 system_profiler SPDisplaysDataType | grep Resolution ``` **输出示例**: ``` Resolution: 2560 x 1440 (QHD/WQHD - Wide Quad High Definition) ``` ### 方法 5:Linux 专用(xrandr 命令) ```bash # 终端执行 xrandr | grep -w connected ``` **输出示例**: ``` HDMI-1 connected primary 2560x1440+0+0 (normal left inverted right x axis y axis) 597mm x 336mm ``` ### 解释说明 1. **主显示器**:操作系统设置的主要显示设备 2. **多显示器系统**:`screeninfo` 库可获取所有显示器的详细参数 3. **分辨率单位**:像素(例如 1920x1080 表示水平 1920 像素,垂直 1080 像素) 4. **推荐方法**: - 简单需求:使用 `tkinter`(无需安装) - 多显示器:使用 `screeninfo` 库
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值