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,控制显示器功能用的命令完成的,会用到ddcutil和xrandr。
在亮度调节后台的命令优先使用 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
包含了基础的工具集
- 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())- 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)read_config.py 和 write_config.py
读写配置,没有特别内容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