- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
Gtk3 丰富 text widget机械(基于 GtkTextBuffer 和 GtkTextView )同时具有 "begin-user-action"和 "end-user-actions"信号,允许快速方便地处理用户输入(并将其与应用程序对缓冲区或 View 生成的更改区分开来)。
但是Qt5好像没有类似的东西。例如,我不完全的理解是 QTextEdit::insertHtml或 QTextDocument::contentsChange或 QTextDocument::contentsChanged不会将与用户输入(键盘或粘贴等)相关的更改与应用程序完成的更改分开。
我的想法是一些面向语法的编辑器。
我可能误解了 Qt5 富文本编辑器支持。
(对于好奇的人:我正在用 C 和 GTK 重新设计和重新实现我的 MELT monitor 到用 C++11 和 Qt5 暂时称为 Basixmo 的东西;所有都是 GPL 免费软件,但我没有编码但 Qt5 的东西)
我有一个窗口,其中有一个按钮 say
和一个 QTextEdit
作为它的中央小部件。当我单击该按钮时,一个 "hello"
字符串被插入到文档中,我称之为 application 更改(您可以想象该按钮被替换为不相关的内容给用户,例如一些网络输入)。当我在文本编辑器中键入一些按键时,还会从该用户操作 更改中插入一些字符串。我想区分两者。
#include <QApplication>
#include <QMainWindow>
#include <QTextEdit>
#include <QToolBar>
#include <fstream>
#include <iostream>
int main(int argc, char**argv)
{
QApplication app(argc, argv);
auto win = new QMainWindow;
auto tb = win->addToolBar("Basile example");
auto ted = new QTextEdit;
win->setCentralWidget(ted);
tb->addAction("say",[=]{ted->insertPlainText("hello");});
auto doc = ted->document();
QObject::connect(doc,&QTextDocument::contentsChange,
[=](int pos, int removedchars, int addedchars)
{ std::clog << "contentChange: pos=" << pos
<< " removedchars=" << removedchars
<< " addedchars=" << addedchars
<< std::endl; });
win->show();
app.exec();
delete win;
}
//// Local Variables:
//// compile-command: "g++ -std=c++11 -Wall -g $(pkg-config --cflags Qt5Core Qt5Widgets Qt5Gui) -fPIC $(pkg-config --libs Qt5Core Qt5Widgets Qt5Gui) -o eqb eqb.cc"
//// End:
但是当我运行上面的代码时,contentsChange
信号(连接到我的 lambda 函数输出到 std::clog
)被触发用于用户操作更改和应用程序更改。
我不关心在 QTextEdit
、QTextDocument
或 QTextCursor
级别工作,但我想将用户操作更改分开(键入 QTextEdit
小部件,或使用鼠标单击和菜单粘贴等...)来自应用程序更改。我想避免在小部件事件级别工作(例如,在我自己的类中为 QWidget::keyPressEvent
重新定义一个虚拟成员函数,等等),特别是因为我不确定 所有影响QTextEdit
实例的可能事件。
顺便说一句,我的问题可能过于笼统:如何设计和编码像 emacs
一样可编写脚本的编辑器正在使用 genuine Qt5 编码风格和 C 中的小部件++11(当然是通过嵌入一些可编写脚本的解释器 à la Guile)。
附言。如果那很重要,我的桌面系统运行 Debian/testing/x86-64。 Qt是5.6.1版本,我的代码是用GCC 6.2编译的;编译命令在最后的宽评里。
最佳答案
在您的特定情况下,您感兴趣的信号是在 QTextDocument
对象上发出的,该对象是 QTextEdit
的一部分。
您可以在 lambda 中使用 QSignalBlocker
来阻止发出这些信号:
#include <QSignalBlocker>
// ...
tb->addAction("say", [=]{
const QSignalBlocker blocker{ted->document()};
ted->insertPlainText("hello");
});
这样,当应用程序更改文档的上下文时,您将不会再收到contentsChange
信号。
参见 official documentation了解更多详情。
请注意,QTextEdit
上的信号未被禁止。
它们可能绑定(bind)到 QTextDocument
的那些并传播(如果您对这些细节感兴趣,可以查看类的代码)。
如果您想区分用户更改和应用程序更改,您现在可以扩展该类并添加要从您的 lambda 中发出的自定义信号(例如,internalContentChange
)。
否则,直接调用一个方法就可以了。
要做什么主要取决于具体问题和软件的设计方式。
作为旁注和评论中提到的,更多细节可以更好地解释其工作原理。QTextEdit
(让我说)转发 insertPlainText
请求到内部 QTextDocument
。因此,后者发出的信号被 QTextEdit
捕获并传播。
这就是为什么上述技巧通过抑制内部类上的信号而适用于特定情况。换句话说,QTextEdit
既有自己的信号,又充当其组件(主要是 QTextDocument
)发出的某些信号的再发射器。
为了清楚起见,我尽量保持简单,但您可以通过查看存在的类来了解请求和信号的流程 here (公共(public)存储库)。
特别是,here是 QTextEdit
组件将 insertPlainText
调用转发给内部 QTextEditControl
的地方组件,它本身就是一个 QWidgetTextControl
和 forwards the call到内部游标...等等。
路径太长,无法在此处进行全面分析。
关于c++ - 使用 QTextEdit 检测用户输入(并将其与应用程序更改区分开来),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40332168/
不确定是否可能,但只是想知道 CSS 中是否有一种方法来区分两种浏览器,即 IE6 和 IE8,因为我有一个我需要应用的样式,但 IE6 和 IE8 的值需要不同,即 ul.sf-menu li li
我正在为 C 库编写 C++ 抽象。 C 库有几个用于标识远程资源的 ID 的类型定义: typedef int color_id; typedef int smell_id; typedef int
有谁知道当以编程方式遍历 Word 文档时,您可以判断一个段落是否构成目录的一部分(或者实际上,构成字段一部分的任何其他内容)。 我提出这个问题的原因是我有一个 VB 程序,它应该从文档中提取前几段实
假设我的数据集包含三列:id(标识)、case(字符)和 value(数字)。这是我的数据集: tdata <- data.frame(id=c(1,1,1,1,2,2,2,2,3,3,3,3,4,4
我在解释 gcc (4.8.2) 警告和错误时遇到问题。更准确地说,很难分辨一个问题在哪里结束,另一个问题从哪里开始。我只能通过控制台访问构建机器,因此不能选择使用 IDE。 我真的需要能够快速区分个
我想创建一个泛型类型,它只从类定义中选择修饰的方法。 function test(ctor: any, methodName: any) {} class A { @test publ
是否有规范的 base-R 方法来确定函数参数是否是对象名称而不是文字/表达式? 虽然通常不鼓励使用 NSE,但偶尔会有人有一个好主意并想使用它。 data.frame 是我认为“方便”的最简单用例:
我已经实现了 didSelectRowAtIndexPath 和accessoryButtonTappedForRowWithIndexPath 似乎永远不会触发。但是,didSelectRowAtI
我需要确定数据框中的哪些列是小数,哪些是字符串。 使用 df.dtypes 为两种列类型提供“对象”: import pandas as pd import decimal data = {'dec1
有没有办法在 Vim 中区分隐藏缓冲区和事件缓冲区? 我需要确定窗口中的缓冲区是否处于事件状态,以便可以切换它。 尝试了 bufloaded、bufexists 和 buflisted,但它们对于事件
在 JavaScript 中区分事件的最佳方法是什么。 实际上有两点我感兴趣。第一点是事件中是否有类似 id 的东西(这对于调试目的非常有用)。另一点是有更好的方法来区分 mousedown 和 mo
我有一个 php 页面,里面有多个表单。 "> "> " value=""> " value=""> 这些表单是通过循环遍历 MySQL 上的所有数据而生成的。每个表单和输入都
Pony 有一个未参数化的异常值。 不幸的是,我经常有一些代码想要抛出不同类型的异常,并且我需要知道它们是什么,以便正确处理它们——例如,简单地说,当停止程序时,向用户提供以下信息很重要正确的错误消息
出于对所有神圣事物的热爱,您如何区分预定义的 .NET 异常类中的不同“异常风格”? 例如,一段代码可能会抛出 XmlException在以下条件下: 文档的根元素为NULL 文档中的字符无效 文档太
正如您在下面看到的,我创建了一个 JComboBox,其中“选项”数组中的元素作为列表中的选项。 当选择列表中的特定项目时,我想显示 JLabels“一个”或“两个”。例如。选择选项一显示“一”,选择
我有一个表,其中包含四列用户名、产品名称、产品价格和一个名为 item_paid 的 boolean 列。相同的产品名称可以作为重复条目插入到表中。但是有没有办法区分一行和重复行?或者我应该创建一个名
是否可以使用反射来区分仅 getter 属性和表达式主体属性? class MyClass { DateTime GetterOnly { get; } DateTime Expres
我即将为一个学校项目制作一个小程序,该程序应该能够识别通过 MIDI 钢琴输入演奏的和弦(这只是其中的一部分)。 目前为止,每次按下和每次释放 MIDI 键盘上的某个键,我都会得到一个 ShortMe
我正在使用“自动”反序列化器从 Kafka 消费 Avro 序列化消息,例如: props.put( ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFI
我需要从两个表中检索数据。第一个是事件列表,第二个是 field 列表。 我在两个表中都有一个同名的字段:events.venue(这是一个 ID),venues.venue 是地点的名称,比如“bl
我是一名优秀的程序员,十分优秀!