隐藏QLineEdit闪烁光标

时间:2014-08-07 10:52:53

标签: qt cursor hide caret qlineedit

我正在研究QT v5.2

我需要永久隐藏QLineEdit的闪烁光标(插入符号)。 但与此同时,我希望QLineEdit可以编辑(因此readOnly和/或设置可编辑的false不适合我)。

我已经在QLineEdit处于焦点时更改背景颜色,因此我将知道正在编辑哪个QLineEdit小部件。 根据我的要求,光标(闪烁文本光标)显示不应该在那里。

我已尝试styleSheets,但我无法隐藏光标( {color:transparent; text-shadow:0px 0px 0px black;} )

有人可以告诉我怎样才能实现这个目标?

5 个答案:

答案 0 :(得分:10)

没有标准的方法可以做到这一点,但您可以使用隐藏光标的setReadOnly方法。当您调用此方法时,它会禁用键的处理,因此您需要强制它。 继承自QLineEdit并重新实现keyPressEvent

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

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

答案 1 :(得分:3)

作为一种解决方法,您可以创建一行QTextEdit并将光标的宽度设置为setCursorWidth

对于单行QTextEdit,您应该继承QTextEdit并执行以下操作:

  1. 禁用自动换行。
  2. 禁用滚动条(AlwaysOff)。
  3. setTabChangesFocus(true)
  4. 将sizePolicy设置为(QSizePolicy::ExpandingQSizePolicy::Fixed
  5. 重新执行keyPressEvent()以忽略输入/返回时的事件
  6. 重新实现sizeHint以返回尺寸,具体取决于字体。
  7. 实施是:

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

答案 2 :(得分:0)

我遇到了同样的问题,但setReadOnly不是一个可行的选择,因为它也改变了其他地方的UI行为。

在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实例外。

答案 3 :(得分:0)

不要复杂:

在QtDesigner中,
1.转到lineEdit的属性选项卡
2.将 focusPolicy 更改为 ClickFocus

就这样...

答案 4 :(得分:0)

我发现的最直接的东西是从这个 github repo 中偷来的: https://github.com/igogo/qt5noblink/blob/master/qt5noblink.cpp

基本上,您只想禁用 Qt 认为在某种程度上是好的 UX 的内部“闪烁计时器”(提示闪烁的光标从来都不是好的 UX,也永远不会是好的 - 也许尝试颜色或突出显示那里的设计窥视)。

所以代码很简单:

from PyQt5 import QtGui


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

瞧。