Есть ли способ сделать окно прозрачным, но при этом получать ввод мыши? (Я успешно создал инструмент для обрезки с помощью Tkinter, но не хочу использовать tkinter)
Это мой код, использующий PySide6 (работает на Mac):
from PySide6 import QtWidgets, QtCore, QtGui
from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QScreen, QPixmap
import sys
using_debug_mode = None
class DraggingPanel(QWidget):
def __init__(self, callback=None, cancel_callback=None):
super().__init__()
self.callback = callback
self.cancel_callback = cancel_callback
self.start_x = None
self.start_y = None
self.rect:QtCore.QRect = None
window_tools.set_frameless(self)
###
# method 1: cannot click on the window
'''
widget.setAttribute(QtCore.Qt.WA_TranslucentBackground)
'''
# method 2: cannot click on the window
'''
self.setStyleSheet('background-color: #00000000;')
'''
# method 3: when opacity 0 and h > 0:
def do_capture():
screen_cap = QScreen.grabWindow(QApplication.primaryScreen(), 0, 0,
screen.width(),
screen.height())
to_img_scale_x = lambda val: round(val * screen_cap.width()/screen.width())
to_img_scale_y = lambda val: round(val * screen_cap.height()/screen.height())
screen_cap = screen_cap.copy(to_img_scale_x(x1),
to_img_scale_y(y1),
to_img_scale_x(w),
to_img_scale_y(h)) if True else screen_cap
if using_debug_mode: print("Screenshot taken!")
QtCore.QTimer.singleShot(1, lambda: self.callback(screen_cap) and self.deleteLater())
QtCore.QTimer.singleShot(1, do_capture)
else:
if using_debug_mode: print("Screenshot canceled!")
QtCore.QTimer.singleShot(1, lambda: self.cancel_callback() and self.deleteLater())
### Tools ###
class window_tools:
@staticmethod
def set_flag(widget:QWidget, flag: QtCore.Qt, on=True):
# Get current flags and remove the FramelessWindowHint flag
widget.setWindowFlag(flag, on=on)
@staticmethod
def set_no_entity_mode(widget:QWidget, transparent_no_enitity=True, frameless = True):
"the mouse can click behind the window."
window_tools.set_flag(widget, QtCore.Qt.FramelessWindowHint, on=frameless)
widget.setAttribute(QtCore.Qt.WA_TranslucentBackground, on=transparent_no_enitity)
def set_bg_to_almost_transparent(widget):
"Opacity: 1/255, Clickable\n\n`widget.setStyleSheet('background-color: #01000000;')`"
widget.setStyleSheet('background-color: #01000000;')
@staticmethod
def set_frameless(widget, on = True):
window_tools.set_flag(widget, QtCore.Qt.FramelessWindowHint, on=on)
@staticmethod
def set_always_on_top(widget, on = True):
window_tools.set_flag(widget, QtCore.Qt.WindowStaysOnTopHint, on=on)
@staticmethod
def create_window(title="", borderless=False, always_on_top=False, width=300, height=300):
# Create a new QWidget (or QMainWindow)
new_window = QWidget()
new_window.setWindowTitle(title)
# Set window flags based on parameters
new_window.setWindowFlag(QtCore.Qt.FramelessWindowHint, borderless)
new_window.setWindowFlag(QtCore.Qt.WindowStaysOnTopHint, always_on_top)
# Set the size of the window
new_window.resize(width, height)
return new_window
class screen:
@staticmethod
def size():
return app_using.primaryScreen().size()
@staticmethod
def width():
return screen.size().width()
@staticmethod
def height():
return screen.size().height()
### main function ###
app_using: QApplication = None
def launch_screenshot_panel(Qapp: QApplication, on_screenshot=None, on_cancel=None, debug_logging=False):
"Please STORE the returned widget to prevent garbage collection"
global using_debug_mode, app_using
using_debug_mode = debug_logging
app_using = Qapp
panel = DraggingPanel(on_screenshot, on_cancel)
panel.show()
return panel
if __name__ == "__main__":
if not QtWidgets.QApplication.instance():
app = QtWidgets.QApplication(sys.argv)
else:
app = QtWidgets.QApplication.instance()
def on_screenshot(img: QPixmap):
img.save("a.png")
quit()
def on_screenshot_cancelled():
print("cancelled callback!")
panel = launch_screenshot_panel(app, on_screenshot=on_screenshot, on_cancel=on_screenshot_cancelled, debug_logging=True)
sys.exit(app_using.exec())
Подробнее здесь: https://stackoverflow.com/questions/791 ... ble-window