Скрыть мигающий курсор QLineEdit

Я работаю над QT v5.2

Мне нужно скрыть мигающий курсор (курсор) QLineEdit навсегда. Но в то же время я хочу, чтобы QLineEdit был редактируемым (поэтому readOnly и/или установка редактируемого false не является для меня опцией).

Я уже меняю цвет фона QLineEdit, когда он находится в фокусе, поэтому я буду знать, какой виджет QLineEdit редактируется. Для моего требования курсор (мигающий текстовый курсор) не должен отображаться там.

Я пробовал таблицы стилей, но не могу скрыть курсор ({цвет: прозрачный; текст-тень: 0px 0px 0px черный;})

может кто-нибудь, пожалуйста, дайте мне знать, как я могу этого достичь?

спасибо, Эш!--1-->

3 ответов


не существует стандартного способа сделать это, но вы можете использовать setReadOnly метод, который скрывает курсор. Когда вы вызываете этот метод, он отключает обработку ключей, поэтому вам нужно будет заставить его. Наследовать от QLineEdit и переопределить keyPressEvent.

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

void LineEdit::keyPressEvent(QKeyEvent* e)
{
  setReadOnly(false);
  __super::keyPressEvent(e);
  setReadOnly(true);
}

в качестве обходного пути вы можете создать одну строку QTextEdit и установите ширину курсора на ноль с помощью setCursorWidth.

для одной строки QTextEdit вы должны подкласс QTextEdit и сделать следующее:

  1. отключить перенос слов.
  2. отключить полосы прокрутки (AlwaysOff).
  3. setTabChangesFocus(true).
  4. установите значение sizePolicy в (QSizePolicy::Expanding, QSizePolicy::Fixed)
  5. Reimplement keyPressEvent() игнорировать событие, когда Enter / Return хит
  6. Reimplement sizeHint для возврата размера в зависимости от шрифта.

реализация :

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

теперь вы можете создать экземпляр TextEdit и установите ширину курсора на ноль:

textEdit->setCursorWidth(0);

я столкнулся с той же проблемой, но setReadOnly не является жизнеспособным вариантом потому, что он изменяет поведение интерфейса в других местах тоже.

где-то на Qt-форуме я нашел следующее решение, которое фактически решает проблему именно там, где она возникает, не оказывая влияния на другие части.

на первом шаге вам нужно вывести из QProxyStyle и заменить pixelMetric функции:

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

пользовательская функция просто обрабатывает QStyle::PM_TextCursorWidth и вперед в противном случае.

в пользовательском LineEdit конструктор класса вы можете использовать новый стиль следующим образом:

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

и не забудьте удалить его в деструкторе, так как владение стилем не передается (см. документацию). Вы можете, конечно, передать форму стиля снаружи вашему LineEdit экземпляр, если хотите.