Brightness Controller-源码记录
2026/7/22 4:25:37 网站建设 项目流程

Brightness Controller 亮度控制

  • 一、概述
  • 二、ddcutil 与 xrandr
    • 1. ddcutil
    • 2. xrandr
  • 三、部分代码解析
    • 1. icons
    • 2. ui
    • 3. util
    • init.py

一、概述

项目:https://github.com/LordAmit/Brightness.git


原理:Brightness Controlle 是我在 Ubuntu 发现上调节亮度的一个工具,我觉得很好用,我后面对它的实现比较感兴趣,就去找了他的源项目来满足我的好奇心,也许后面做项目时候会使用,特此记录。

这个小工具是用的python3实现,界面使用pyqt5,控制显示器功能用的命令完成的,会用到ddcutilxrandr

在亮度调节后台的命令优先使用 ddcutil,其次才使用 xrandr。

二、ddcutil 与 xrandr

这里简单介绍一下 ddcutil

1. ddcutil

ddcutil 是一个 Linux 命令行工具,用于通过 DDC/CI(Display Data Channel Command Interface) 协议与支持该协议的显示器进行通信。它允许用户通过软件控制显示器的硬件设置,如亮度、对比度、输入源等。

  • . 调整显示器设置:
    • 亮度、对比度、音量等。
    • 切换输入源(如 HDMI、DP、VGA)。
    • 调整色彩设置(如 RGB 值)。
  • 查询显示器信息:
    • 获取显示器的制造商、型号、支持的 DDC/CI 功能等。
  • 自动化控制:
    • 通过脚本批量调整多台显示器的设置。

2. xrandr

xrandr 是一个 Linux 命令行工具,用于管理和配置显示器的分辨率、刷新率、旋转、镜像以及多显示器布局。它是 X Window System(Xorg)的一部分,主要用于与 X Server 交互,因此仅适用于运行 Xorg 的 Linux 系统。

三、部分代码解析

1. icons

图标文件夹

2. ui

界面文件夹,包含ui文件,以及通过uic工具对ui文件生成的pyqt脚本文件。

3. util

包含了基础的工具集

  1. check_displays.py
    查询连接的显示器工具,通过运行 xrandr --query 命令,再对输出用正则匹配出显示器名称
importsubprocessimportshleximportredefquery_xrandr():query="xrandr --query"xrandr_output=subprocess.Popen(shlex.split(query),stdout=subprocess.PIPE,stderr=subprocess.STDOUT)stdout,stderr=xrandr_output.communicate()returnstr(stdout,"utf-8")defextract_displays(output):pattern=re.compile(r'\b({0})\b'.format("connected"),flags=re.IGNORECASE)lines=output.splitlines()connected=[lineforlineinlinesifpattern.search(line)]connected_displays=list(map(lambdadisplay:display.split()[0],connected))returnconnected_displaysdefdetect_display_devices():""" Detects available displays. returns connected_displays This contains the available device names compatible with xrandr """returnextract_displays(query_xrandr())if__name__=='__main__':print(detect_display_devices())
  1. executor.py
    封装的进程控制器,是调节亮度这些的后台命令
importsubprocessdefexecute_command(string_cmd):subprocess.check_output(string_cmd,shell=True)

使用的例子如下

defchange_value_pr(self,value):"""Changes Primary Display Red ratio"""cmd_value="xrandr\--output%s \--brightness%s\--gamma%s:%s:%s"%\(self.display1,self.values[self.ui.primary_brightness.value()-1],self.values[value],self.values[self.ui.primary_green.value()],self.values[self.ui.primary_blue.value()])Executor.execute_command(cmd_value)
  1. read_config.py 和 write_config.py
    读写配置,没有特别内容

  2. QtSingleApplication.py
    封装的单例工具,它的核心作用是确保同一时间只有一个应用程序实例运行,并支持在多个实例尝试启动时,将消息传递给已经运行的实例,并激活窗口。使用QLocalSocket 作为进程间通信的工具。

classQtSingleApplication(QApplication):messageReceived=Signal(str)def__init__(self,id,*argv):super(QtSingleApplication,self).__init__(*argv)self._id=idself._activationWindow=Noneself._activateOnMessage=False# Is there another instance running?self._outSocket=QLocalSocket()self._outSocket.connectToServer(self._id)self._isRunning=self._outSocket.waitForConnected()ifself._isRunning:# Yes, there is.self._outStream=QTextStream(self._outSocket)self._outStream.setCodec('UTF-8')else:# No, there isn't.self._outSocket=Noneself._outStream=Noneself._inSocket=Noneself._inStream=Noneself._server=QLocalServer()self._server.listen(self._id)self._server.newConnection.connect(self._onNewConnection)defisRunning(self):returnself._isRunningdefid(self):returnself._iddefactivationWindow(self):returnself._activationWindowdefsetActivationWindow(self,activationWindow,activateOnMessage=True):self._activationWindow=activationWindow self._activateOnMessage=activateOnMessagedefactivateWindow(self):ifnotself._activationWindow:returnself._activationWindow.setWindowState(self._activationWindow.windowState()&~Qt.WindowMinimized)self._activationWindow.raise_()self._activationWindow.activateWindow()defsendMessage(self,msg):ifnotself._outStream:returnFalseself._outStream<<msg<<'\n'self._outStream.flush()returnself._outSocket.waitForBytesWritten()def_onNewConnection(self):ifself._inSocket:self._inSocket.readyRead.disconnect(self._onReadyRead)self._inSocket=self._server.nextPendingConnection()ifnotself._inSocket:returnself._inStream=QTextStream(self._inSocket)self._inStream.setCodec('UTF-8')self._inSocket.readyRead.connect(self._onReadyRead)ifself._activateOnMessage:self.activateWindow()def_onReadyRead(self):whileTrue:msg=self._inStream.readLine()ifnotmsg:breakself.messageReceived.emit(msg)

使用例子

defmain():UUID='PHIR-HWOH-MEIZ-AHTA'APP=QtSingleApplication(UUID,sys.argv)ifAPP.isRunning():sys.exit(0)WINDOW=MyApplication()WINDOW.APP=APP APP.setActivationWindow(WINDOW)WINDOW.show()sys.exit(APP.exec_())if__name__=="__main__":main()

init.py

此文件为完整的应用

  • main:为启动函数

  • class HelpForm :帮助界面

  • class AboutForm :关于界面

  • class LicenseForm :版权页面

  • MyApplication:为主应用

下面change_value_p 开头为 调节主屏幕
下面change_value_s 开头为 调节副屏幕

pbr 是主屏亮度,pr,pg,pb 分别代表 RGB分量

看看调节主屏幕代码,

调节色彩分量均是使用 xrandr

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询