如何使用 PyQt 更改光标形状?

发布于 2024-12-17 02:58:13 字数 189 浏览 3 评论 0原文

我有一个简单的应用程序,它运行的进程可能会持续几分钟才能完成。我试图向用户表明它正在处理请求 - 例如将光标更改为沙漏。

但我不能完全让它正常工作。我的所有尝试要么导致错误,要么没有效果。而且我似乎错误地调用了光标形状,因为 PyQt4.Qt.WaitCursor 返回模块不包含它的错误。

向用户指示进程正在运行的正确方法是什么?

I have a simple application that runs a process that can last for several minutes before completing. I am trying to provide an indication to the user that it is processing the request - such as changing the cursor to an hourglass.

But I cannot quite get it to work right. All of my attempts have resulted in either an error or had no effect. And I seem to be calling the cursor shapes incorrectly, since PyQt4.Qt.WaitCursor returns an error that the module does not contain it.

What is the correct way to indicate to the user that the process is running?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

想挽留 2024-12-24 02:58:14

我认为 QApplication.setOverrideCursor 就是您正在寻找的:

<强>PyQt6:

from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QApplication
...
QApplication.setOverrideCursor(Qt.CursorShape.WaitCursor)
# do lengthy process
QApplication.restoreOverrideCursor()

PyQt5

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication
...
QApplication.setOverrideCursor(Qt.WaitCursor)
# do lengthy process
QApplication.restoreOverrideCursor()

PyQt4

from PyQt4.QtCore import Qt
from PyQt4.QtGui import QApplication
...
QApplication.setOverrideCursor(Qt.WaitCursor)
# do lengthy process
QApplication.restoreOverrideCursor()

I think QApplication.setOverrideCursor is what you're looking for:

PyQt6:

from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QApplication
...
QApplication.setOverrideCursor(Qt.CursorShape.WaitCursor)
# do lengthy process
QApplication.restoreOverrideCursor()

PyQt5:

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication
...
QApplication.setOverrideCursor(Qt.WaitCursor)
# do lengthy process
QApplication.restoreOverrideCursor()

PyQt4:

from PyQt4.QtCore import Qt
from PyQt4.QtGui import QApplication
...
QApplication.setOverrideCursor(Qt.WaitCursor)
# do lengthy process
QApplication.restoreOverrideCursor()
心清如水 2024-12-24 02:58:14

虽然卡梅伦和大卫的答案非常适合在整个函数上设置等待光标,但我发现上下文管理器最适合为代码片段设置等待光标:

from contextlib import contextmanager
from PyQt4 import QtCore
from PyQt4.QtGui import QApplication, QCursor

@contextmanager
def wait_cursor():
    try:
        QApplication.setOverrideCursor(QCursor(QtCore.Qt.WaitCursor))
        yield
    finally:
        QApplication.restoreOverrideCursor()

然后将冗长的流程代码放入 with 块中:

with wait_cursor():
    # do lengthy process
    pass

While Cameron's and David's answers are great for setting the wait cursor over an entire function, I find that a context manager works best for setting the wait cursor for snippets of code:

from contextlib import contextmanager
from PyQt4 import QtCore
from PyQt4.QtGui import QApplication, QCursor

@contextmanager
def wait_cursor():
    try:
        QApplication.setOverrideCursor(QCursor(QtCore.Qt.WaitCursor))
        yield
    finally:
        QApplication.restoreOverrideCursor()

Then put the lengthy process code in a with block:

with wait_cursor():
    # do lengthy process
    pass
烟酒忠诚 2024-12-24 02:58:14

ekhumoro的解决方案是正确的。该解决方案是为了风格而进行的修改。我使用了 ekhumor 所做的,但使用了 python 装饰器。

from PyQt4.QtCore import Qt
from PyQt4.QtGui import QApplication, QCursor, QMainWidget

def waiting_effects(function):
    def new_function(self):
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        try:
            function(self)
        except Exception as e:
            raise e
            print("Error {}".format(e.args[0]))
        finally:
            QApplication.restoreOverrideCursor()
    return new_function

我可以将装饰器放在我希望微调器处于活动状态的任何方法上。

class MyWigdet(QMainWidget):

    # ...

    @waiting_effects
    def doLengthyProcess(self):
        # do lengthy process
        pass

ekhumoro's solution is correct. This solution is a modification for the sake of style. I used what ekhumor's did but used a python decorator.

from PyQt4.QtCore import Qt
from PyQt4.QtGui import QApplication, QCursor, QMainWidget

def waiting_effects(function):
    def new_function(self):
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        try:
            function(self)
        except Exception as e:
            raise e
            print("Error {}".format(e.args[0]))
        finally:
            QApplication.restoreOverrideCursor()
    return new_function

I can just put the decorator on any method I would like the spinner to be active on.

class MyWigdet(QMainWidget):

    # ...

    @waiting_effects
    def doLengthyProcess(self):
        # do lengthy process
        pass
翻身的咸鱼 2024-12-24 02:58:14

这样更好:

def waiting_effects(function):
    def new_function(*args, **kwargs):
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        try:
            return function(*args, **kwargs)
        except Exception as e:
            raise e
            print("Error {}".format(e.args[0]))
        finally:
            QApplication.restoreOverrideCursor()
    return new_function

Better this way:

def waiting_effects(function):
    def new_function(*args, **kwargs):
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        try:
            return function(*args, **kwargs)
        except Exception as e:
            raise e
            print("Error {}".format(e.args[0]))
        finally:
            QApplication.restoreOverrideCursor()
    return new_function
春花秋月 2024-12-24 02:58:14

您可以使用类 QgsTemporaryCursorOverride https://qgis.org/api/classQgsTemporaryCursorOverride.html

但是在Python中,您应该使用Python上下文管理器,它现在包含在PyQGIS中:

from qgis.PyQt.QtCore import Qt
from qgis.utils import OverrideCursor

with OverrideCursor(Qt.WaitCursor):
    do_a_slow(operation)

You can use the class QgsTemporaryCursorOverride https://qgis.org/api/classQgsTemporaryCursorOverride.html

But in Python, you should use the Python context manager which is now included in PyQGIS :

from qgis.PyQt.QtCore import Qt
from qgis.utils import OverrideCursor

with OverrideCursor(Qt.WaitCursor):
    do_a_slow(operation)
我爱人 2024-12-24 02:58:14
from qtpy import QtCore, QtGui, QtWidgets

def waiting_effect(function):
    def waiting(*args, **kwargs):
        QtWidgets.QApplication.setOverrideCursor(
             QtCore.Qt.CursorShape(QtCore.Qt.CursorShape.WaitCursor)
        )
        try:
            function(*args, **kwargs)     
        finally:
            QtWidgets.QApplication.restoreOverrideCursor()

如果使用 PyQt5/PySide2,这可能有用,可以很好地处理具有多个参数的装饰函数。

from qtpy import QtCore, QtGui, QtWidgets

def waiting_effect(function):
    def waiting(*args, **kwargs):
        QtWidgets.QApplication.setOverrideCursor(
             QtCore.Qt.CursorShape(QtCore.Qt.CursorShape.WaitCursor)
        )
        try:
            function(*args, **kwargs)     
        finally:
            QtWidgets.QApplication.restoreOverrideCursor()

If using PyQt5/PySide2, this might be of use, works nicely with decorating functions that have multiple arguments.

做个少女永远怀春 2024-12-24 02:58:14

根据我的说法,添加光标的最佳方法是使用装饰器。通过这种方式,您只需将光标添加到该函数作为装饰器即可运行任何函数

import decorator
@decorator.decorator
def showWaitCursor(func, *args, **kwargs):
    QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor)
    try:
        return func(*args, **kwargs)
    finally:
        QtWidgets.QApplication.restoreOverrideCursor()

@showWaitCursor
def youFunc():
    # Long process

The best way to add the cursor according to me would be by using the decorators. By this way you can run any function by just adding the cursor to that function as decorator

import decorator
@decorator.decorator
def showWaitCursor(func, *args, **kwargs):
    QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor)
    try:
        return func(*args, **kwargs)
    finally:
        QtWidgets.QApplication.restoreOverrideCursor()

@showWaitCursor
def youFunc():
    # Long process
内心荒芜 2024-12-24 02:58:14

我发现我经常需要做的是:

QApplication.setOverrideCursor(Qt.WaitCursor)
QApplication.ProcessEvents()
...
QApplication.restoreOverrideCursor()

但是!在 GUI 初始化期间,我发现由于某种原因需要进行修改:

self.ui.show()  # Or your equivalent code to show the widget
QApplication.processEvents()
QApplication.setOverrideCursor(Qt.WaitCursor)
app.processEvents()
...
QApplication.restoreOverrideCursor()

否则光标不会“恢复”,直到鼠标经过修改它的小部件(如 QLineEdit),类似于 @Guimoute 提到的

I find I often need to do:

QApplication.setOverrideCursor(Qt.WaitCursor)
QApplication.ProcessEvents()
...
QApplication.restoreOverrideCursor()

However! During init of the GUI, I've found a modification needs to be made for some reason:

self.ui.show()  # Or your equivalent code to show the widget
QApplication.processEvents()
QApplication.setOverrideCursor(Qt.WaitCursor)
app.processEvents()
...
QApplication.restoreOverrideCursor()

Otherwise the cursor does not "restore" until the mouse passes over a widget that modifies it (like a QLineEdit), similar to what @Guimoute mentioned

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文