【问题标题】:How to disable middle button functionality of QTextEdit?如何禁用 QTextEdit 的中间按钮功能?
【发布时间】:2013-07-23 13:40:11
【问题描述】:

我不希望鼠标中键在我的 QTextEdit 中粘贴文本。此代码不起作用。 TextEdit 继承 QTextEdit。鼠标中键粘贴后,它会粘贴复制的文本。

void TextEdit::mousePressEvent ( QMouseEvent * e ) {
    if (e->button() == Qt::MidButton) {
        e->accept();
        return;
    };
    QTextEdit::mousePressEvent(e);
}

【问题讨论】:

  • 我无法复制此内容,中键不会为我粘贴任何文本。
  • 还有,平台是Linux吗?
  • @Merlin069 根据QTextControlPrivate::mouseReleaseEvent的源代码,其他平台好像也可以中键粘贴。
  • 是的,我正在 Linux 下编码
  • @alexisdm - 这很有趣,我以前从未注意到这一点。我问的是 Linux,因为它通常是默认的操作系统行为,不像 OSX 和 Windows。

标签: c++ linux qt qtextedit


【解决方案1】:

由于鼠标点击通常在按钮释放时注册,您应该重新定义mouseReleaseEvent 函数。

您甚至不需要重新定义mousePressEvent,因为该函数根本不处理中间按钮。

【讨论】:

    【解决方案2】:

    我假设您在这里使用的是 Linux;在您处理鼠标事件之前,在窗口中单击鼠标右键可能会触发插入 mime 数据,这就是它仍在粘贴文本的原因。

    因此,根据 Qt docs for paste:-“要修改 QTextEdit 可以粘贴的内容以及粘贴方式,请重新实现虚拟 canInsertFromMimeData() 和 insertFromMimeData() 函数。”

    【讨论】:

    • 重新定义 insertFromMimeData 也会改变拖放的工作方式,而不仅仅是改变中间按钮的行为。
    • @alexisdm 重新定义它并检查是否按下了鼠标中键,否则调用基类函数将提供所需的行为。
    • 我并不是说它不起作用,我只是说应该避免在与鼠标无关的函数中添加鼠标处理代码。
    • 它并不是真正处理鼠标,而是对其状态做出反应,这发生在 GUI 应用程序的整个代码中。
    • @Merlin069 我试过你说的,但是当insertFromMimeData() 被调用时,鼠标中键已经被释放,所以我不知道它是否是从中键单击中调用的
    【解决方案3】:

    我也遇到过同样的情况,也就是说:我的CustomQTextEdit 的某些部分必须不可编辑

    因为我真的很喜欢鼠标中键粘贴功能,所以我不想禁用它。所以,这是我使用的(或多或少快速和肮脏的编码)解决方法:

    void QTextEditHighlighter::mouseReleaseEvent(QMouseEvent *e)
    {
    
        QString prev_text;
        if (e->button() == Qt::MidButton) {
            // Backup the text as it is before middle button click
            prev_text = this->toPlainText();
            // And let the paste operation occure...
            //        e->accept();
            //        return;
        }
    
        // !!!!
        QTextEdit::mouseReleaseEvent(e);
        // !!!!
    
        if (e->button() == Qt::MidButton) {
    
            /*
             * Keep track of the editbale ranges (up to you).
             * My way is a single one range inbetween the unique
             * tags "//# BEGIN_EDIT" and "//# END_EDIT"...
             */
            QRegExp begin_regexp = QRegExp("(^|\n)(\\s)*//# BEGIN_EDIT[^\n]*(?=\n|$)");
            QRegExp end_regexp  = QRegExp("(^|\n)(\\s)*//# END_EDIT[^\n]*(?=\n|$)");
    
            QTextCursor from = QTextCursor(this->document());
            from.movePosition(QTextCursor::Start);
    
            QTextCursor cursor_begin = this->document()->find(begin_regexp, from);
            QTextCursor cursor_end = this->document()->find(end_regexp, from);
            cursor_begin.movePosition(QTextCursor::EndOfBlock);
            cursor_end.movePosition(QTextCursor::StartOfBlock);
            int begin_pos = cursor_begin.position();
            int end_pos = cursor_end.position();
    
            if (!(cursor_begin.isNull() || cursor_end.isNull())) {
                // Deduce the insertion index by finding the position
                // of the first character that changed between previous
                // text and the current "after-paste" text
                int insert_pos; //, end_insert_pos;
                std::string s_cur = this->toPlainText().toStdString();
                std::string s_prev = prev_text.toStdString();
    
                int i_max = std::min(s_cur.length(), s_prev.length());
                for (insert_pos=0; insert_pos < i_max; insert_pos++) {
                    if (s_cur[insert_pos] != s_prev[insert_pos])
                        break;
                }
                // If the insertion point is not in my editable area: just restore the 
                // text as it was before the paste occured
                if (insert_pos < begin_pos+1 || insert_pos > end_pos) {
                    // Restore text (ghostly)
                    ((MainWindow *)this->topLevelWidget())->disconnect(this, SIGNAL(textChanged()), ((MainWindow *)this->topLevelWidget()), SLOT(on_textEdit_CustomMacro_textChanged()));
                    this->setText(prev_text);
                    ((MainWindow *)this->topLevelWidget())->connect(this, SIGNAL(textChanged()), ((MainWindow *)this->topLevelWidget()), SLOT(on_textEdit_CustomMacro_textChanged()));
                }
            }
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2015-02-23
      • 1970-01-01
      • 2017-08-23
      • 2010-10-04
      • 1970-01-01
      • 1970-01-01
      • 2020-01-20
      • 2022-10-12
      • 2011-09-15
      相关资源
      最近更新 更多