【问题标题】:Change cursor for QMessageBox and SaveFileDialog更改 QMessageBox 和 SaveFileDialog 的光标
【发布时间】:2018-07-27 12:09:20
【问题描述】:

在 PyQt5 中,我可以使用以下方法更改对象的光标:

    Object.setCursor(QCursor(Qt.PointingHandCursor))

对于其他按钮,我使用此类,但它不会更改 QmessageBoxQfiledialog 中的光标:

class QPushButton(QPushButton):
    def __init__(self, parent=None):
        super(QPushButton, self).__init__(parent)
        self.setCursor(QCursor(Qt.PointingHandCursor))

如何更改QMessageBoxQFileDialog 中所有按钮的光标?

消息框方法示例

def onNotConnected(self):
        err = QMessageBox.question(
            self, DONGLE_NOT_CONN, DONGLE_NOT_CONN_MSG, QMessageBox.Ok | QMessageBox.Cancel)
        if err == QMessageBox.Ok:            
            self.updating_thread(self.device_code)
        else:
            self.restart_program()

【问题讨论】:

  • QMessageBox 有 setCursor() 方法。
  • 你指的是 QMessageBox 的静态方法吗,你可以解释一下。
  • QFileDialog 也有 setCursor() 方法。
  • 你认为从一个类继承到另一个同名的类是正确的吗?
  • 它们正在改变,因为您的 QPushButtons 不是原来的 QPushButtons,而是您在 python 中构建它们,而是 QMessageBox 和 QFileDialog 的静态方法是在 C++ 中创建的

标签: python python-3.x pyqt pyqt5 qmessagebox


【解决方案1】:

QMessageBoxQFileDialog 具有 setCursor() 方法,因为它们继承自 QWidget。但您的问题在于静态方法,因为您无法直接访问该对象。

所以解决方案是利用这些静态方法的一个特殊特性:它们是顶层,所以我们可以使用QApplication.topLevelWidgets() 对其进行过滤,但另一个问题是它们是阻塞的,因此不会同步执行任何内容,所以诀窍是使用QTimer

from PyQt5 import QtCore, QtGui, QtWidgets

def onTimeout():
    for w in QtWidgets.QApplication.topLevelWidgets():
        if isinstance(w, QtWidgets.QMessageBox):
            for button in w.buttons():
                button.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent=None)
        self.show()

        QtCore.QTimer.singleShot(0, onTimeout)
        res = QtWidgets.QMessageBox.question(self, 
            "title", 
            "text",  
            QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)


if __name__ == '__main__':
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

同样在您的示例中,我们可以使用 QMessageBox 的父级过滤过滤器,并且可能 QFileDialog 是窗口。

from PyQt5 import QtCore, QtGui, QtWidgets


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent=None)
        self.show()

        QtCore.QTimer.singleShot(0, self.onTimeout)
        msgBox = QtWidgets.QMessageBox.question(self, 
            "title", 
            "text",  
            QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)

        QtCore.QTimer.singleShot(0, self.onTimeout)
        fileName, _ = QtWidgets.QFileDialog.getSaveFileName(self, 
            "Save File",
            QtCore.QDir.homePath(),
            "Images (*.png *.xpm *.jpg)",
            "",
            QtWidgets.QFileDialog.DontUseNativeDialog)

    def onTimeout(self):
        for w in QtWidgets.QApplication.topLevelWidgets():
            if isinstance(w, QtWidgets.QMessageBox) and w.parent() == self:
                for button in w.buttons():
                    button.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
            elif isinstance(w, QtWidgets.QFileDialog) and w.parent() == self:
                for button in w.findChildren(QtWidgets.QPushButton):
                    button.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))



if __name__ == '__main__':
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

【讨论】:

    猜你喜欢
    • 2018-12-10
    • 2016-06-23
    • 1970-01-01
    • 2017-12-23
    • 1970-01-01
    • 2010-11-16
    • 1970-01-01
    • 2016-06-11
    • 2021-07-19
    相关资源
    最近更新 更多