In PyQt5 I can change the cursor for an object using:
Object.setCursor(QCursor(Qt.PointingHandCursor))
For the other buttons I use this class but it does not change the cursors in QmessageBox
or Qfiledialog
:
class QPushButton(QPushButton):
def __init__(self, parent=None):
super(QPushButton, self).__init__(parent)
self.setCursor(QCursor(Qt.PointingHandCursor))
How can I change the cursor for ALL buttons in QMessageBox
and QFileDialog
?
Example of a Messagebox method
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
and QFileDialog
have the setCursor()
method since they inherit from QWidget
. But the problem in your case is with static methods since you can not access the object directly.
So the solution is to take advantage of a particular characteristic of these static methods: they are topLevels, so we can filter it using QApplication.topLevelWidgets()
, but the other problem is that they are blocking so nothing will be executed synchronously, so The trick is to use 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_())
Also in your sample that we can filter the filter using the parent of the QMessageBox and possibly the QFileDialog is the window.
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_())