【问题标题】:Hide QLineEdit blinking cursor隐藏 QLineEdit 闪烁光标
【发布时间】:2014-09-30 14:00:11
【问题描述】:

我正在开发 QT v5.2

我需要永久隐藏QLineEdit 的闪烁光标(插入符号)。 但同时,我希望 QLineEdit 是可编辑的(所以 readOnly 和/或设置可编辑的 false 对我来说不是一个选项)。

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

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

有人可以告诉我如何实现这一目标吗?

【问题讨论】:

    标签: qt hide caret qlineedit


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

      1. 禁用自动换行。
      2. 禁用滚动条 (AlwaysOff)。
      3. setTabChangesFocus(true)
      4. 将 sizePolicy 设置为 (QSizePolicy::Expanding, QSizePolicy::Fixed)
      5. 重新实现 keyPressEvent() 以在按下 Enter/Return 时忽略该事件
      6. 重新实现 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);
      

      【讨论】:

        【解决方案3】:

        我遇到了同样的问题,但 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 实例。

        【讨论】:

          【解决方案4】:

          不要复杂:

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

          就是这样……

          【讨论】:

            【解决方案5】:

            我发现的最直接的东西是从这个 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)
            

            瞧。

            【讨论】:

              【解决方案6】:

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2019-10-01
                • 2011-04-09
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2018-01-26
                相关资源
                最近更新 更多