PyQT 鼠标光标手动动画。反复改变光标所需的形状。在主线程上工作。不适用于单独的线程。怎么会这样?

问题描述 投票:0回答:1


我想在 PyQT(PySide6) 应用程序中实现更改光标。由于没有找到 QCursor 的动画 gif 支持 -> 决定创建我自己的手动动画。

到目前为止:

  1. 在不使用多线程的情况下手动更改光标时 -> 一切正常,但显然用户在光标更改时无法执行任何操作。这就是为什么我决定从单独的线程执行更改光标代码指令。
  2. 但是,当在多线程的帮助下更改光标时 - > 由于某种原因,光标仅在鼠标从小部件移开然后移回到小部件上时才会改变。 为什么???当光标静止在小部件上时,我需要更改鼠标光标...看起来我缺少某种额外的隐藏更新,当执行鼠标光标的更改时,不是从主线程,而是从单独的线程...
import sys
import time
from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtWidgets import *

class Window(QWidget):
    def __init__(self, parent = None):
        QWidget.__init__(self, parent)
        self.label1 = QLabel("No multithread")
        self.label1.mouseReleaseEvent = self.showText1

        self.label2 = QLabel("With mulithread")
        self.label2.mouseReleaseEvent = self.showText2

        layout = QHBoxLayout(self)
        layout.addWidget(self.label1)
        layout.addWidget(self.label2)

        self.threadpool = QThreadPool()

    def showText1(self, event):
        print("Label 1 clicked")
        self.change_cursor1()

    def change_cursor1(self):
        for i in range(10):
            self.label1.setCursor(Qt.CursorShape.WaitCursor)
            print("Left label -> Cursor set to 1")
            time.sleep(1)
            self.label1.setCursor(Qt.CursorShape.CrossCursor)
            print("Left label -> Cursor set to 2")
            time.sleep(1)

    def showText2(self, event):
        print("Label 2 clicked")
        self.start_multithread_function()

    def change_cursor2(self):
        for i in range(10):
            self.label2.setCursor(Qt.CursorShape.WaitCursor)
            print("Right label -> Cursor set to 1")
            time.sleep(1)
            self.label2.setCursor(Qt.CursorShape.CrossCursor)
            print("Right label -> Cursor set to 2")
            time.sleep(1)

    def start_multithread_function(self):
        # Pass the function to execute
        worker = Worker(self.change_cursor2)
        self.threadpool.start(worker) # Execute

class Worker(QRunnable): # The container for the parallel work to perform
    def __init__(self, fn):
        super().__init__()
        self.fn = fn

    def run(self):
        print("[Worker] run()")
        self.fn()

if __name__ == "__main__": 
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec())
qt python-multithreading pyside pyside6 qcursor
1个回答
0
投票

正如 @musicamante 提到的解决方案是使用 QTimer 类实例并将 .timeout() 插槽绑定到函数,这会定期更改光标的形状。无需多线程。

© www.soinside.com 2019 - 2024. All rights reserved.