如何禁用 QTextEdit 的中间按钮功能?

Posted

技术标签:

【中文标题】如何禁用 QTextEdit 的中间按钮功能?【英文标题】:How to disable middle button functionality of 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。 【参考方案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()));
            
        
    


【讨论】:

以上是关于如何禁用 QTextEdit 的中间按钮功能?的主要内容,如果未能解决你的问题,请参考以下文章

在推送 QPushButton 时将文本从 QTextEdit 发送到 QListWidget - Qt

Qt中通过点击一个QPushButton来实现QTextEdit的PageUp/PageDown功能

Qt:如何在 QVBoxLayout 中交替对齐 QTextEdit?

Qt 4.8.7 内存伪影

qt中如何向QTextEdit发送一个鼠标滚轮向下滚动一下的事件?

Qt - 暂时禁用所有事件或窗口功能?