当前位置: 首页 > article >正文

Brightness Controller-源码记录

Brightness Controller 亮度控制

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

一、概述

项目:https://github.com/SunStorm2018/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 命令,再对输出用正则匹配出显示器名称
import subprocess
import shlex
import re

def query_xrandr():
    query = "xrandr --query"
    xrandr_output = subprocess.Popen(shlex.split(query), stdout=subprocess.PIPE,
                                     stderr=subprocess.STDOUT)
    stdout, stderr = xrandr_output.communicate()
    return str(stdout, "utf-8")

def extract_displays(output):
    pattern = re.compile(r'\b({0})\b'.format("connected"), flags=re.IGNORECASE)
    lines = output.splitlines()
    connected = [line for line in lines if pattern.search(line)]
    connected_displays = list(
        map(lambda display: display.split()[0], connected))
    return connected_displays

def detect_display_devices():
    """
    Detects available displays.
    returns connected_displays
    This contains the available device names compatible with xrandr
    """
    return extract_displays(query_xrandr())


if __name__ == '__main__':
    print(detect_display_devices())
  1. executor.py
    封装的进程控制器,是调节亮度这些的后台命令
import subprocess

def execute_command(string_cmd):
    subprocess.check_output(string_cmd, shell=True)

使用的例子如下

def change_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 作为进程间通信的工具。

class QtSingleApplication(QApplication):
    messageReceived = Signal(str)

    def __init__(self, id, *argv):

        super(QtSingleApplication, self).__init__(*argv)
        self._id = id
        self._activationWindow = None
        self._activateOnMessage = False

        # Is there another instance running?
        self._outSocket = QLocalSocket()
        self._outSocket.connectToServer(self._id)
        self._isRunning = self._outSocket.waitForConnected()

        if self._isRunning:
            # Yes, there is.
            self._outStream = QTextStream(self._outSocket)
            self._outStream.setCodec('UTF-8')
        else:
            # No, there isn't.
            self._outSocket = None
            self._outStream = None
            self._inSocket = None
            self._inStream = None
            self._server = QLocalServer()
            self._server.listen(self._id)
            self._server.newConnection.connect(self._onNewConnection)

    def isRunning(self):
        return self._isRunning

    def id(self):
        return self._id

    def activationWindow(self):
        return self._activationWindow

    def setActivationWindow(self, activationWindow, activateOnMessage=True):
        self._activationWindow = activationWindow
        self._activateOnMessage = activateOnMessage

    def activateWindow(self):
        if not self._activationWindow:
            return
        self._activationWindow.setWindowState(
            self._activationWindow.windowState() & ~Qt.WindowMinimized)
        self._activationWindow.raise_()
        self._activationWindow.activateWindow()

    def sendMessage(self, msg):
        if not self._outStream:
            return False
        self._outStream << msg << '\n'
        self._outStream.flush()
        return self._outSocket.waitForBytesWritten()

    def _onNewConnection(self):
        if self._inSocket:
            self._inSocket.readyRead.disconnect(self._onReadyRead)
        self._inSocket = self._server.nextPendingConnection()
        if not self._inSocket:
            return
        self._inStream = QTextStream(self._inSocket)
        self._inStream.setCodec('UTF-8')
        self._inSocket.readyRead.connect(self._onReadyRead)
        if self._activateOnMessage:
            self.activateWindow()

    def _onReadyRead(self):
        while True:
            msg = self._inStream.readLine()
            if not msg: break
            self.messageReceived.emit(msg)

使用例子

def main():
    UUID = 'PHIR-HWOH-MEIZ-AHTA'
    APP = QtSingleApplication(UUID, sys.argv)
    if APP.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
在这里插入图片描述


http://www.kler.cn/a/519552.html

相关文章:

  • 独立开发者常见开发的应用有哪些
  • 正则表达式基础与应用
  • 第22篇:Python开发进阶:详解使用SQLAlchemy进行ORM数据库编程技术
  • OpenEuler学习笔记(八):安装OpenEuler
  • 14-6-3C++STL的list
  • 如何使用群晖NAS配置MySQL与phpMyAdmin远程管理
  • 商业航天更青睐哪些芯片
  • 网易Android开发面试题200道及参考答案 (下)
  • 长短期记忆网络LSTM
  • python爬虫入门(一) - requests库与re库,一个简单的爬虫程序
  • Kubernetes可视化界面
  • three.js+WebGL踩坑经验合集(3):THREE.Line的射线检测问题(不是阈值方面的,也不是难选中的问题)
  • IDEA2020同时使用SVN和GIT
  • DBO优化GRNN回归预测matlab
  • Altium Designer脚本开发不支持功能集锦
  • 接口(完)
  • 快速更改WampServer根目录php脚本
  • 如何写美赛(MCM/ICM)论文中的Summary部分
  • kafka-保姆级配置说明(consumer)
  • 【算法】递归型枚举与回溯剪枝初识