Hide QLineEdit blinking cursor
Asked Answered
N

6

8

I am working on QT v5.2

I need to hide the blinking cursor (caret) of QLineEdit permanently. But at the same time, I want the QLineEdit to be editable (so readOnly and/or setting editable false is not an option for me).

I am already changing the Background color of the QLineEdit when it is in focus, so I will know which QLineEdit widget is getting edited. For my requirement, cursor (the blinking text cursor) display should not be there.

I have tried styleSheets, but I can't get the cursor hidden ( {color:transparent; text-shadow:0px 0px 0px black;} )

Can someone please let me know how can I achieve this?

Natatory answered 7/8, 2014 at 10:52 Comment(0)
H
11

There is no standard way to do that, but you can use setReadOnly method which hides the cursor. When you call this method it disables processing of keys so you'll need to force it. Inherit from QLineEdit and reimplement keyPressEvent.

LineEdit::LineEdit(QWidget* parent)
 : QLineEdit(parent)
{
  setReadOnly(true);      
}

void LineEdit::keyPressEvent(QKeyEvent* e)
{
  setReadOnly(false);
  __super::keyPressEvent(e);
  setReadOnly(true);
}
Hershel answered 7/8, 2014 at 11:57 Comment(0)
S
3

As a workaround you can create a single line QTextEdit and set the width of the cursor to zero by setCursorWidth.

For a single line QTextEdit you should subclass QTextEdit and do the following:

  1. Disable word wrap.
  2. Disable the scroll bars (AlwaysOff).
  3. setTabChangesFocus(true).
  4. Set the sizePolicy to (QSizePolicy::Expanding, QSizePolicy::Fixed)
  5. Reimplement keyPressEvent() to ignore the event when Enter/Return is hit
  6. Reimplement sizeHint to return size depending on the font.

The implementation is :

#include <QTextEdit>
#include <QKeyEvent>
#include <QStyleOption>
#include <QApplication>


class TextEdit : public QTextEdit
{
public:
        TextEdit()
        {
                setTabChangesFocus(true);
                setWordWrapMode(QTextOption::NoWrap);
                setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
                setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
                setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
                setFixedHeight(sizeHint().height());
        }
        void keyPressEvent(QKeyEvent *event)
        {
                if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)
                        event->ignore();
                else
                        QTextEdit::keyPressEvent(event);
        }
        QSize sizeHint() const
        {
                QFontMetrics fm(font());
                int h = qMax(fm.height(), 14) + 4;
                int w = fm.width(QLatin1Char('x')) * 17 + 4;
                QStyleOptionFrameV2 opt;
                opt.initFrom(this);
                return (style()->sizeFromContents(QStyle::CT_LineEdit, &opt, QSize(w, h).
                        expandedTo(QApplication::globalStrut()), this));
        }
};

Now you can create an instance of TextEdit and set the cursor width to zero :

textEdit->setCursorWidth(0);
Streamlet answered 7/8, 2014 at 12:14 Comment(0)
A
2

Don't get complicated:

In QtDesigner ,
1.Go the the lineEdit 's property tab
2.Change focusPolicy to ClickFocus

That's it...

Allround answered 3/5, 2020 at 11:33 Comment(0)
I
1

I ran into the same problem but setReadOnly is not a viable option because it alters the UI behavior in other places too.

Somewhere in a Qt-forum I found the following solution that actually solves the problem exactly where it occurs without having impact on other parts.

In the first step you need to derive from QProxyStyle and overwrite the pixelMetric member function:

class CustomLineEditProxyStyle : public QProxyStyle
{
public:
    virtual int pixelMetric(PixelMetric metric, const QStyleOption* option = 0, const QWidget* widget = 0) const
    {
        if (metric == QStyle::PM_TextCursorWidth) 
            return 0;

        return QProxyStyle::pixelMetric(metric, option, widget);
    }
};

The custom function simply handles QStyle::PM_TextCursorWidth and forwards otherwise.

In your custom LineEdit class constructor you can then use the new Style like this:

m_pCustomLineEditStyle = new CustomLineEditProxyStyle();
setStyle(m_pCustomLineEditStyle);

And don't forget to delete it in the destructor since the ownership of the style is not transferred (see documentation). You can, of course, hand the style form outside to your LineEdit instance if you wish.

Include answered 9/12, 2015 at 11:43 Comment(0)
B
1

Most straight forward thing I found was stolen from this github repo: https://github.com/igogo/qt5noblink/blob/master/qt5noblink.cpp

Basically you just want to disable the internal "blink timer" Qt thinks is somehow good UX (hint blinking cursors never were good UX and never will be - maybe try color or highlighting there eh design peeps).

So the code is pretty simple:

from PyQt5 import QtGui


app = QtGui.QApplication.instance()
app.setCursorFlashTime(0)

voilà.

Baughman answered 26/5, 2021 at 16:41 Comment(0)
W
1

Solution in python:

# somelibraries

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.layout = QVBoxLayout()
        
        self.setFocus() # this is what you need!!!

        container = QWidget()
        container.setLayout(self.layout)

        # Set the central widget of the Window.
        self.setCentralWidget(container)


app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()
Woodrow answered 20/10, 2021 at 8:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.