我正在嘗試開發一個簡單的墻紙管理器,但我找不到任何方法將我的 PyQt 視窗放置在當前墻紙和使用 XLib 的桌面圖示之間(在 Windows 上它更容易使用 pywin32 完美運行)。
我正在嘗試開發一個簡單的墻紙管理器,但我找不到任何方法將我的 PyQt 視窗放置在當前墻紙和使用 XLib 的桌面圖示之間(在 Windows 上它更容易使用 pywin32 完美運行)。
我試圖重新設定視窗,但它不起作用(可能這不是正確的策略)。我已經在 Ubuntu/Unity、Mint/Cinnamon 和 Raspbian 上嘗試過這個,但沒有成功。
編輯:我嘗試更改視窗屬性(在我的示例代碼中注釋),以及創建一個新視窗,將其屬性更改為桌面,并將該新視窗設定為目標視窗父視窗......但沒有成功。事實上,新創建的視窗并沒有顯示在桌面圖示后面(見下面的修改代碼)
歡迎任何幫助或線索!!!
#!/usr/bin/python
# -*- coding: utf-8 -*-
import signal
import sys
from PyQt5 import QtWidgets, QtCore, QtGui
import Xlib
import Xlib.X
import Xlib.display
import ewmh
import traceback
DISP = Xlib.display.Display()
SCREEN = DISP.screen()
ROOT = SCREEN.root
EWMH = ewmh.EWMH(_display=DISP, root=ROOT)
class Window(QtWidgets.QMainWindow):
def __init__(self, *args, **kwargs):
QtWidgets.QMainWindow.__init__(self, *args, **kwargs)
caption = "TestIt"
self.setWindowTitle(caption)
self.setWindowFlags(QtCore.Qt.WindowStaysOnBottomHint | QtCore.Qt.FramelessWindowHint)
screenSize = QtWidgets.QApplication.primaryScreen().size()
x = screenSize.width()
y = screenSize.height()
self.setGeometry(0, 0, x, y)
self.bkg_label = QtWidgets.QLabel()
self.bkg_label.setGeometry(0, 0, x, y)
pixmap = resizeImageWithQT("resourcesB/Doom.jpg", x, y)
self.bkg_label.setPixmap(pixmap)
self.layout().addWidget(self.bkg_label)
self.bkg_label.show()
sendBehind(caption)
def resizeImageWithQT(src, width, height, keepAspect=True):
try:
pixmap = QtGui.QPixmap(src)
if keepAspect:
pixmap_resized = pixmap.scaled(int(width), int(height), QtCore.Qt.KeepAspectRatioByExpanding, QtCore.Qt.SmoothTransformation)
else:
pixmap_resized = pixmap.scaled(int(width), int(height), QtCore.Qt.IgnoreAspectRatio, QtCore.Qt.SmoothTransformation)
except:
pixmap_resized = None
return pixmap_resized
def sendBehind(name):
def getAllWindows():
# windows = EWMH.getClientList() # This will return the "user" apps only
windows = ROOT.query_tree().children
return windows
def getWindowsWithTitle(title):
matches = []
for win in getAllWindows():
if title == EWMH.getWmName(win):
matches.append(win)
return matches
def getActiveWindow():
win_id = EWMH.getActiveWindow()
if win_id:
return win_id
return None
win = getWindowsWithTitle(name)
if win:
win = win[0]
w = DISP.create_resource_object('window', win)
# https://stackoverflow.com/questions/58885803/can-i-use-net-wm-window-type-dock-ewhm-extension-in-openbox
# Does not sends current window below. It does with the new window, but not behind the desktop icons
# w.change_property(DISP.intern_atom('_NET_WM_WINDOW_TYPE'), Xlib.Xatom.ATOM,
# 32, [DISP.intern_atom("_NET_WM_WINDOW_TYPE_DESKTOP"), ],
# Xlib.X.PropModeReplace)
# w.map()
# DISP.next_event()
# DISP.next_event()
newWin = ROOT.create_window(0, 0, 500, 500, 1, SCREEN.root_depth,
background_pixel=SCREEN.black_pixel,
event_mask=Xlib.X.ExposureMask | Xlib.X.KeyPressMask)
newWin.change_property(DISP.intern_atom('_NET_WM_WINDOW_TYPE'), Xlib.Xatom.ATOM,
32, [DISP.intern_atom("_NET_WM_WINDOW_TYPE_DESKTOP"), ],
Xlib.X.PropModeReplace)
newWin.map()
DISP.next_event()
DISP.next_event()
w.reparent(newWin, 0, 0)
def sigint_handler(*args):
# https://stackoverflow.com/questions/4938723/what-is-the-correct-way-to-make-my-pyqt-application-quit-when-killed-from-the-co
app.closeAllWindows()
def exception_hook(exctype, value, tb):
# https://stackoverflow.com/questions/56991627/how-does-the-sys-excepthook-function-work-with-pyqt5
traceback_formated = traceback.format_exception(exctype, value, tb)
traceback_string = "".join(traceback_formated)
print(traceback_string, file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
if "python" in sys.executable.lower():
# This will allow to manage Ctl-C interruption (e.g. when running from IDE)
signal.signal(signal.SIGINT, sigint_handler)
timer = QtCore.QTimer()
timer.start(500)
timer.timeout.connect(lambda: None)
# This will allow to show some tracebacks (not all, anyway)
sys._excepthook = sys.excepthook
sys.excepthook = exception_hook
win = Window()
win.show()
try:
app.exec_()
except:
pass
uj5u.com熱心網友回復:
我最終(并且偶然地)找到了解決方案。無需使用 Xlib。這段 PyQt 代碼成功了。我必須找到一種更智能的方法,將桌面(桌面圖示)顯示在墻紙之上。目前正在模擬桌面上的滑鼠單擊。
#!/usr/bin/python
# -*- coding: utf-8 -*-
import signal
import sys
from PyQt5 import QtWidgets, QtCore, QtGui
import Xlib
import Xlib.X
import Xlib.display
import ewmh
import traceback
DISP = Xlib.display.Display()
SCREEN = DISP.screen()
ROOT = SCREEN.root
EWMH = ewmh.EWMH(_display=DISP, root=ROOT)
class Window(QtWidgets.QMainWindow):
def __init__(self, *args, **kwargs):
QtWidgets.QMainWindow.__init__(self, *args, **kwargs)
caption = "TestIt"
self.setWindowTitle(caption)
if "Linux" in platform.platform():
parent.setAttribute(QtCore.Qt.WA_X11NetWmWindowTypeDesktop)
parent.setFocusPolicy(QtCore.Qt.NoFocus)
parent.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents)
parent.setAttribute(QtCore.Qt.WA_InputMethodTransparent)
parent.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowStaysOnBottomHint | QtCore.Qt.FramelessWindowHint)
screenSize = QtWidgets.QApplication.primaryScreen().size()
x = screenSize.width()
y = screenSize.height()
self.setGeometry(0, 0, x, y)
self.bkg_label = QtWidgets.QLabel()
self.bkg_label.setGeometry(0, 0, x, y)
pixmap = resizeImageWithQT("resourcesB/Doom.jpg", x, y)
self.bkg_label.setPixmap(pixmap)
self.layout().addWidget(self.bkg_label)
self.bkg_label.show()
sendBehind()
def resizeImageWithQT(src, width, height, keepAspect=True):
try:
pixmap = QtGui.QPixmap(src)
if keepAspect:
pixmap_resized = pixmap.scaled(int(width), int(height), QtCore.Qt.KeepAspectRatioByExpanding, QtCore.Qt.SmoothTransformation)
else:
pixmap_resized = pixmap.scaled(int(width), int(height), QtCore.Qt.IgnoreAspectRatio, QtCore.Qt.SmoothTransformation)
except:
pixmap_resized = None
return pixmap_resized
def sendBehind():
pyautogui.leftclick(x=1, y=1)
def sigint_handler(*args):
# https://stackoverflow.com/questions/4938723/what-is-the-correct-way-to-make-my-pyqt-application-quit-when-killed-from-the-co
app.closeAllWindows()
def exception_hook(exctype, value, tb):
# https://stackoverflow.com/questions/56991627/how-does-the-sys-excepthook-function-work-with-pyqt5
traceback_formated = traceback.format_exception(exctype, value, tb)
traceback_string = "".join(traceback_formated)
print(traceback_string, file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
if "python" in sys.executable.lower():
# This will allow to manage Ctl-C interruption (e.g. when running from IDE)
signal.signal(signal.SIGINT, sigint_handler)
timer = QtCore.QTimer()
timer.start(500)
timer.timeout.connect(lambda: None)
# This will allow to show some tracebacks (not all, anyway)
sys._excepthook = sys.excepthook
sys.excepthook = exception_hook
win = Window()
win.show()
try:
app.exec_()
except:
pass
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/367750.html
上一篇:兩次呼叫函式并每次保存不同的值
