Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PyQt: How to reset the cursor to whatever it's hovering over

Very small issue:

I've written a small IDE with a text editing widget based on a QPlainTextEdit. When you move the mouse over it the cursor becomes a caret/text cursor as expected. If you hit F5 the window is disabled and a small script runs after which the window is re-enabled and the text area is given focus.

Somehow, this changes the cursor from a text cursor to a pointer. If you move the cursor off the text area and then back onto it, it turns into a text cursor again.

Is there some way to trigger this refresh action programmatically?


Update: It seems to be something to do with having a progress bar:

#!/usr/bin/env python
import sys
import time
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import Qt

class TinyIDE(QtGui.QMainWindow):

    def __init__(self, filename=None):
        super(TinyIDE, self).__init__()
        self.setWindowTitle('Tiny IDE test')

        # Add menu item
        menu = self.menuBar()
        menu_run = menu.addMenu('&Run')
        tool_run = QtGui.QAction('&Run', self)
        tool_run.setShortcut('F5')
        tool_run.triggered.connect(self.action_run)
        menu_run.addAction(tool_run)

        # Add editor
        self._editor = QtGui.QPlainTextEdit()
        self._editor.setPlainText('Press F5 to run')
        self.setCentralWidget(self._editor)
        self._editor.setFocus()

    def action_run(self):
        pbar = None
        try:
            self.setEnabled(False)

            pbar = QtGui.QProgressDialog('Running script', 'Cancel', 0, 10)
            pbar.setWindowModality(Qt.WindowModal)
            pbar.setAutoClose(False)
            pbar.setAutoReset(False)
            pbar.show()

            for i in xrange(10):
                time.sleep(0.2)
                pbar.setValue(1 + i)
                QtGui.QApplication.processEvents()

        finally:

            QtGui.QApplication.processEvents()
            pbar.close()
            pbar.deleteLater()
            self.setEnabled(True)
            self._editor.setFocus()

if __name__ == '__main__':
    a = QtGui.QApplication([])
    a.connect(a, QtCore.SIGNAL('lastWindowClosed()'), a, QtCore.SLOT('quit()'))
    w = TinyIDE()
    w.show()
    sys.exit(a.exec_())

I've tested it on Linux (Fedora 21) with Python 2.7.8 and PyQt4 version 4.8.6

Steps to reproduce:

  1. Run the script
  2. Place the mouse cursor over the text area, it should turn into a text cursor
  3. Press F5, wait for the progress bar to go away, leave the mouse hovering over the text area, it should turn into a pointer

Expected result: Once the progress bar goes away the cursor, still hovering over the text area, should revert to a text cursor

Actual result: The cursor stays a pointer, until it's moved off and back on to the text area

like image 837
Michael Clerx Avatar asked Apr 06 '15 22:04

Michael Clerx


People also ask

How do I get my cursor back to normal?

Press Windows Key +I and go to Ease of access and select Mouse option from the left Pane and try to set default settings for mouse and see if it helps. Hope this information was helpful.

How do I change the cursor on my QT?

To set a cursor shape use QCursor::setShape() or use the QCursor constructor which takes the shape as argument, or you can use one of the predefined cursors defined in the Qt::CursorShape enum.


1 Answers

I was only able to work around this (what is obviously a bug):

        pos = QtGui.QCursor.pos()
        QtGui.QCursor.setPos(0, 0)
        QtGui.QCursor.setPos(pos)

The funny thing is, setPos(0, 0) on my system (some Ubuntu) doesn't even move the mouse, so if I just call it, the mouse stays where it is and the cursor changes back immediately after even a slightest move (no need to move it away from the editor any more). But the additional setPos() that reverts the position back does the trick, and the cursor updates instantly. This has the added bonus that if you move it away while the computation is in progress, the workaround above still resets the cursor to whatever shape is correct for the place the mouse cursor is actually at.

like image 188
Sergei Tachenov Avatar answered Oct 13 '22 01:10

Sergei Tachenov