我正在创建一个简单的应用程序,其中用户应该能够在屏幕上绘制一个矩形并将坐标报告给外壳或在内部使用。就像各种屏幕截图工具一样,人们可以选择一个区域。
通常与gnome-screenshot -s
或shutter -s -n -e -o test1.png
相同。更像快门。
想法是使用覆盖整个屏幕的半透明覆盖层,并且还应覆盖多个监视器(如果存在)。它也应该覆盖任务栏/状态栏等。然后在此画上。
在测试了各种方法之后,我发现一种解决方案是使用Qt.Popup
窗口标志。通过运行此示例进行了各种测试:
https://doc.qt.io/qt-5/qtwidgets-widgets-windowflags-example.html /
https://code.qt.io/cgit/qt/qtbase.git/tree/examples/widgets/widgets/windowflags?h=5.14
并尝试以下类型和标志:
https://doc.qt.io/qt-5/qt.html#WindowModality-enum(及以下)
我在弹出窗口中遇到的问题是Alt + Tab不起作用。弹出窗口捕获所有关键事件,并且不会传播。除此之外,它似乎可以像我喜欢的那样工作。下面的示例代码。
此外,如果使用Alt + Tab,则在完成窗口切换后,覆盖层应该会捕获焦点。
典型场景:
是否可以在此处启用Alt + Tab?
按Q或Escape关闭窗口/叠加层-或按“关闭”按钮
#!/usr/bin/env python3
import sys
from PyQt5.QtGui import QPainter
from PyQt5.QtWidgets import (QMainWindow, QApplication, QPushButton, QDesktopWidget)
from PyQt5.Qt import Qt
from PyQt5.QtCore import QRect
from PyQt5 import QtWidgets
# class CustomWindow(QLabel):
# class CustomWindow(Qt.Popup):
class CustomWindow(QMainWindow):
def __init__(self):
super().__init__()
def paintEvent(self, event=None):
painter = QPainter(self)
painter.setBrush(Qt.white)
painter.setOpacity(0.3)
painter.drawRect(self.rect())
def keyPressEvent(self, event):
print(event.key())
if event.key() in (Qt.Key_Escape, Qt.Key_Q):
self.close()
# Needed to exit Qt.Popup on close
QtWidgets.QApplication.exit()
def main():
app = QApplication(sys.argv)
# Create the main window
window = CustomWindow()
window.setAttribute(Qt.WA_NoSystemBackground, True)
window.setAttribute(Qt.WA_TranslucentBackground, True)
# Add a panic button in case window does not capture focus or the like
# For testing purpose only
if 1:
pushButton = QPushButton(window)
pushButton.setGeometry(QRect(40, 190, 250, 100))
pushButton.setText("Close")
pushButton.clicked.connect(app.quit)
# Run the application
# If one use fs as option when running, use fullscreen option. This, however,
# hides taskbar etc - so not a solution + not able to span monitors.
if 'fs' in sys.argv:
# window.windowHandle.setScreen(app.screens().last())
monitor = QDesktopWidget().screenGeometry(0)
window.move(monitor.left(), monitor.top())
window.showFullScreen()
else:
window.setWindowFlags(
Qt.FramelessWindowHint
# | Qt.WindowStaysOnTopHint
# | Qt.ToolTip
# | Qt.Dialog
| Qt.Popup
# | Qt.ApplicationModal
# | Qt.WindowMaximized
# | Qt.MaximizeUsingFullscreenGeometryHint
)
window.show()
# Span on all screens
allScreens = QApplication.desktop().geometry()
widgetSize = allScreens.adjusted(0, 0, 0, 0)
window.setGeometry(widgetSize)
sys.exit(app.exec_())
if __name__ == '__main__':
main()