From 7c396a9a40eeddcb2fa5e2697ac7a57fd8b2198f Mon Sep 17 00:00:00 2001 From: Irony <892768447@qq.com> Date: Tue, 13 Apr 2021 14:40:32 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B1=8F=E5=B9=95=E5=8F=98=E5=8C=96=E7=9B=91?= =?UTF-8?q?=E5=90=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/README.md | 10 +- Demo/ScreenNotify.py | 58 ++++++++++++ Demo/ScreenShot/ScreenNotify.png | Bin 0 -> 6270 bytes QtRemoteObjects/SyncUi/ClipboardMaster.py | 105 +++++++++++++++++++++ QtRemoteObjects/SyncUi/ClipboardSlave.py | 107 ++++++++++++++++++++++ README.md | 1 + Test/ColumnView.py | 48 ++++++++++ 7 files changed, 328 insertions(+), 1 deletion(-) create mode 100644 Demo/ScreenNotify.py create mode 100644 Demo/ScreenShot/ScreenNotify.png create mode 100644 QtRemoteObjects/SyncUi/ClipboardMaster.py create mode 100644 QtRemoteObjects/SyncUi/ClipboardSlave.py create mode 100644 Test/ColumnView.py diff --git a/Demo/README.md b/Demo/README.md index 31e582c..3bd9406 100644 --- a/Demo/README.md +++ b/Demo/README.md @@ -23,6 +23,7 @@ - [判断信号是否连接](#20判断信号是否连接) - [调用虚拟键盘](#21调用虚拟键盘) - [动态忙碌光标](#22动态忙碌光标) + - [屏幕变动监听](#23屏幕变动监听) ## 1、重启窗口Widget [运行 RestartWindow.py](RestartWindow.py) @@ -223,4 +224,11 @@ PyQt 结合 Opencv 进行人脸检测; 通过定时器不停的修改光标图片来实现动态效果 -![GifCursor](ScreenShot/GifCursor.gif) \ No newline at end of file +![GifCursor](ScreenShot/GifCursor.gif) + +## 23、屏幕变动监听 +[运行 ScreenNotify.py](ScreenNotify.py) + +通过定时器减少不同的变化信号,尽量保证只调用一次槽函数来获取信息 + +![ScreenNotify](ScreenShot/ScreenNotify.png) \ No newline at end of file diff --git a/Demo/ScreenNotify.py b/Demo/ScreenNotify.py new file mode 100644 index 0000000..33c29cb --- /dev/null +++ b/Demo/ScreenNotify.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Created on 2021/4/13 +@author: Irony +@site: https://github.com/PyQt5 +@email: 892768447@qq.com +@file: ScreenNotify +@description: 屏幕、分辨率、DPI变化通知 +""" +import sys + +from PyQt5.QtCore import QTimer, QRect +from PyQt5.QtWidgets import QApplication, QPlainTextEdit, qApp + + +class Window(QPlainTextEdit): + + def __init__(self, *args, **kwargs): + super(Window, self).__init__(*args, **kwargs) + self.appendPlainText('修改分辨率后查看') + # 记录最后一次的值(减少槽调用) + self.m_rect = QRect() + # 使用定时器来延迟触发最后一次变化 + self.m_timer = QTimer(self, timeout=self.onSolutionChanged) + self.m_timer.setSingleShot(True) # **重要** 保证多次信号尽量少的调用函数 + + # 主要是多屏幕->无屏幕->有屏幕 + qApp.primaryScreenChanged.connect(lambda _: self.m_timer.start(1000)) + # 其它信号最终基本上都会调用该信号 + qApp.primaryScreen().virtualGeometryChanged.connect(lambda _: self.m_timer.start(1000)) + # DPI变化 + qApp.primaryScreen().logicalDotsPerInchChanged.connect(lambda _: self.m_timer.start(1000)) + + def onSolutionChanged(self): + # 获取主屏幕 + screen = qApp.primaryScreen() + if self.m_rect == screen.availableVirtualGeometry(): + return + self.m_rect = screen.availableVirtualGeometry() + # 所有屏幕可用大小 + self.appendPlainText('\navailableVirtualGeometry: {0}'.format(str(screen.availableVirtualGeometry()))) + # 获取所有屏幕 + screens = qApp.screens() + for screen in screens: + self.appendPlainText( + 'screen: {0}, geometry({1}), availableGeometry({2}), logicalDotsPerInch({3}), ' + 'physicalDotsPerInch({4}), refreshRate({5})'.format( + screen.name(), screen.geometry(), screen.availableGeometry(), screen.logicalDotsPerInch(), + screen.physicalDotsPerInch(), screen.refreshRate())) + + +if __name__ == '__main__': + app = QApplication(sys.argv) + w = Window() + w.show() + sys.exit(app.exec_()) diff --git a/Demo/ScreenShot/ScreenNotify.png b/Demo/ScreenShot/ScreenNotify.png new file mode 100644 index 0000000000000000000000000000000000000000..e95330cca5fbf6d60fd5e77cc7cf60b4e7d975da GIT binary patch literal 6270 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 literal 0 HcmV?d00001 diff --git a/QtRemoteObjects/SyncUi/ClipboardMaster.py b/QtRemoteObjects/SyncUi/ClipboardMaster.py new file mode 100644 index 0000000..feefebb --- /dev/null +++ b/QtRemoteObjects/SyncUi/ClipboardMaster.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Created on 2020/7/31 +@author: Irony +@site: https://pyqt.site https://github.com/PyQt5 +@email: 892768447@qq.com +@file: ClipboardMaster +@description: +""" +from PyQt5.QtCore import QUrl, pyqtSlot, pyqtSignal, QLoggingCategory, QVariant, QMimeData +from PyQt5.QtRemoteObjects import QRemoteObjectHost +from PyQt5.QtWidgets import QTextBrowser + +__Author__ = 'Irony' +__Copyright__ = 'Copyright (c) 2019 Irony' +__Version__ = 1.0 + +import sys + + +class WindowMaster(QTextBrowser): + SignalUpdateMimeData = pyqtSignal( + bool, QVariant, # color + bool, QVariant, # html + bool, QVariant, # image + bool, QVariant, # text + bool, QVariant, # urls + ) + + def __init__(self, *args, **kwargs): + super(WindowMaster, self).__init__(*args, **kwargs) + # 监听剪切板 + # clipboard = QApplication.clipboard() + # clipboard.dataChanged.connect(self.on_data_changed) + # 开启节点 + host = QRemoteObjectHost(QUrl('tcp://0.0.0.0:' + sys.argv[1]), parent=self) + host.enableRemoting(self, 'WindowMaster') + self.append('开启节点完成') + + def on_data_changed(self): + # 服务端剪贴板变化后发送到客户端 + clipboard = QApplication.clipboard() + clipboard.blockSignals(True) + mime_data = clipboard.mimeData() + self.SignalUpdateMimeData.emit( + mime_data.hasColor(), mime_data.colorData(), + mime_data.hasHtml(), mime_data.html(), + mime_data.hasImage(), mime_data.imageData(), + mime_data.hasText(), mime_data.text(), + mime_data.hasUrls(), mime_data.urls(), + ) + clipboard.blockSignals(False) + + @pyqtSlot( + bool, QVariant, # color + bool, QVariant, # html + bool, QVariant, # image + bool, QVariant, # text + bool, QVariant, # urls + bool, QVariant # files + ) + def updateMimeData(self, + hasColor, color, + hasHtml, html, + hasImage, image, + hasText, text, + hasUrls, urls, + hasFiles, files, + ): + # 客户端剪切板同步到服务端 + self.append('收到客户端发送的剪贴板') + clipboard = QApplication.clipboard() + clipboard.blockSignals(True) + data = QMimeData() + if hasColor: + data.setColorData(color) + if hasHtml: + data.setHtml(html) + if hasImage: + data.setImageData(image) + if hasText: + data.setText(text) + # if hasUrls: + # data.setUrls(urls) + if hasFiles: + data.setData('') + clipboard.setMimeData(data) + clipboard.blockSignals(False) + + +if __name__ == '__main__': + import cgitb + + cgitb.enable(1, None, 5, '') + from PyQt5.QtWidgets import QApplication + + QLoggingCategory.setFilterRules('qt.remoteobjects.debug=true\n' + 'qt.remoteobjects.warning=true') + + app = QApplication(sys.argv) + w = WindowMaster() + w.show() + sys.exit(app.exec_()) diff --git a/QtRemoteObjects/SyncUi/ClipboardSlave.py b/QtRemoteObjects/SyncUi/ClipboardSlave.py new file mode 100644 index 0000000..bfe9b60 --- /dev/null +++ b/QtRemoteObjects/SyncUi/ClipboardSlave.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Created on 2020/7/31 +@author: Irony +@site: https://pyqt.site https://github.com/PyQt5 +@email: 892768447@qq.com +@file: ClipboardSlave +@description: +""" +from PyQt5.QtCore import QUrl, pyqtSignal, QVariant, QMimeData +from PyQt5.QtRemoteObjects import QRemoteObjectNode, QRemoteObjectReplica +from PyQt5.QtWidgets import QTextBrowser + +__Author__ = 'Irony' +__Copyright__ = 'Copyright (c) 2019 Irony' +__Version__ = 1.0 + + +class WindowSlave(QTextBrowser): + SignalUpdateMimeData = pyqtSignal( + bool, QVariant, # color + bool, QVariant, # html + bool, QVariant, # image + bool, QVariant, # text + bool, QVariant, # urls + bool, QVariant, # files + ) + + def __init__(self, *args, **kwargs): + super(WindowSlave, self).__init__(*args, **kwargs) + # 监听剪切板 + clipboard = QApplication.clipboard() + clipboard.dataChanged.connect(self.on_data_changed) + # 加入Master节点 + node = QRemoteObjectNode(parent=self) + node.connectToNode(QUrl('tcp://{}:{}'.format(sys.argv[1], sys.argv[2]))) + # 获取WindowMaster对象 + self.windowMaster = node.acquireDynamic('WindowMaster') + # 初始化成功后才能去绑定信号等 + self.windowMaster.initialized.connect(self.onInitialized) + # 状态改变 https://doc.qt.io/qt-5/qremoteobjectreplica.html#State-enum + self.windowMaster.stateChanged.connect(self.onStateChanged) + + def onStateChanged(self, newState, oldState): + if newState == QRemoteObjectReplica.Suspect: + self.append('连接丢失') + + def onInitialized(self): + self.SignalUpdateMimeData.connect(self.windowMaster.updateMimeData) + # self.windowMaster.SignalUpdateMimeData.connect(self.updateMimeData) + self.append('绑定信号槽完成') + + def on_data_changed(self): + # 客户端剪贴板变化后发送到远程 + print('on_data_changed') + clipboard = QApplication.clipboard() + clipboard.blockSignals(True) + mime_data = clipboard.mimeData() + files = mime_data.data('text/uri-list') + self.SignalUpdateMimeData.emit( + mime_data.hasColor(), mime_data.colorData(), + mime_data.hasHtml(), mime_data.html(), + mime_data.hasImage(), mime_data.imageData(), + mime_data.hasText(), mime_data.text(), + mime_data.hasUrls(), mime_data.urls(), + True if files else False, files, + ) + clipboard.blockSignals(False) + + def updateMimeData(self, + hasColor, color, + hasHtml, html, + hasImage, image, + hasText, text, + hasUrls, urls + ): + # 远程的剪贴板同步到客户端 + clipboard = QApplication.clipboard() + clipboard.blockSignals(True) + data = QMimeData() + if hasColor: + data.setColorData(color) + if hasHtml: + data.setHtml(html) + if hasImage: + data.setImageData(image) + if hasText: + data.setText(text) + if hasUrls: + data.setUrls(urls) + clipboard.setMimeData(data) + clipboard.blockSignals(False) + + +if __name__ == '__main__': + import sys + import cgitb + + cgitb.enable(1, None, 5, '') + from PyQt5.QtWidgets import QApplication + + app = QApplication(sys.argv) + w = WindowSlave() + w.show() + sys.exit(app.exec_()) diff --git a/README.md b/README.md index 6405705..e4ac617 100644 --- a/README.md +++ b/README.md @@ -253,6 +253,7 @@ https://pyqt.site 论坛是专门针对PyQt5学习和提升开设的网站,分 - [判断信号是否连接](Demo/IsSignalConnected.py) - [调用虚拟键盘](Demo/CallVirtualKeyboard.py) - [动态忙碌光标](Demo/GifCursor.py) + - [屏幕变动监听](Demo/ScreenNotify.py) # QQ群 diff --git a/Test/ColumnView.py b/Test/ColumnView.py new file mode 100644 index 0000000..5ce9859 --- /dev/null +++ b/Test/ColumnView.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Created on 2020/9/14 +@author: Irony +@site: https://pyqt.site https://github.com/PyQt5 +@email: 892768447@qq.com +@file: ColumnView +@description: +""" + +from PyQt5.QtWidgets import QComboBox, QFileSystemModel, QHBoxLayout, QSpacerItem, QSizePolicy + +__Author__ = 'Irony' +__Copyright__ = 'Copyright (c) 2020' +__Version__ = 'Version 1.0' + + +class PathComboBox(QComboBox): + + def __init__(self, *args, is_item=False, **kwargs): + super(PathComboBox, self).__init__(*args, **kwargs) + self.is_item = is_item + if not self.is_item: + self.setEditable(True) + layout = QHBoxLayout(self) + layout.setSpacing(0) + layout.setContentsMargins(0, 0, 0, 23) + layout.addItem(QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)) + else: + self.f_model = QFileSystemModel(self) + self.f_model.setRootPath('') + self.setModel(self.f_model) + + def addWidget(self, widget): + self.layout().insertWidget(self.layout().count()-1, widget) + + +if __name__ == '__main__': + import sys + from PyQt5.QtWidgets import QApplication + + app = QApplication(sys.argv) + w = PathComboBox() + w.show() + w.addWidget(PathComboBox(w, is_item=True)) + sys.exit(app.exec_())