Hide QLineEdit blinking cursor

梦想的初衷 提交于 2019-12-05 06:37:42

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);
}

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);

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!