Я создаю простое приложение, в котором пользователь должен иметь возможность рисовать прямоугольник на экране и сообщать координаты в оболочку или для внутреннего использования. Очень похоже на различные инструменты для создания снимков экрана, где можно выбрать регион.
Как обычно, с gnome-screenshot -s
или shutter -s -n -e -o test1.png
. Больше похоже на затвор.
Идея состоит в том, чтобы использовать полупрозрачное наложение, которое покрывает весь экран И также должно охватывать несколько мониторов, если они присутствуют. Он также должен охватывать панель задач / строку состояния и т. Д. c. Затем нарисуйте это.
После тестирования различных подходов я нашел одно решение - использовать флаг окна 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 (и ниже)
- Qt :: WindowModality
- Qt :: WindowStates
- Qt :: WindowType
Проблема с всплывающим окном заключается в том, что Alt + Tab не работает. Всплывающее окно фиксирует все ключевые события и не распространяется. Помимо этого, кажется, что я работаю так, как мне нравится. Пример кода ниже.
Также при использовании Alt + Tab наложение должно захватывать фокус после выполнения переключения windows.
Типичный сценарий:
- Применение Запущено
- Пользователь использует Alt + Tab для изменения порядка windows
- Пользователь рисует прямоугольник на экране
Есть ли способ включить 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()