我有两个单独的线程。GUI的第一个线程,第二个用于应用程序数据的线程。
最初,我想使用Qundostack和Qundoview。
但是有一个问题 - 此视图直接与堆栈合作:
https://code.woboq.org/qt5/qtbase/src/widgets/widgets/qundoview.cpp.html#_zn10qundomodel20qundomodel20setstackcurrentstackcurrententindexerk11qmodelindex
在这种情况下,我有比赛状况。
为了解决这个问题,我使用qlistview和qabstractlistModel编写了自定义myundoview。现在,我使用排队连接的所有插槽,我在自定义视图模型中存储了"真实"撤消堆栈的轻量级副本。这是相同的大小和"真实"撤消堆栈元素的相同顺序。轻量级元素仅包含undo命令和文本的类型。
现在我还有另一个问题。我不责怪这个((
我有一个qlineedit,当我单击"输入键或丢失的焦点"时,会在值中发出信号。此值依次发送到具有"真实"撤消堆栈的对象(APP模型(。它有效。
,当我与撤消视图互动时,这也不起作用。重复一遍,我不是为此责备。Qundoview具有相同的行为。
逐步:
- 焦点中的Qlineit。
- 更改价值,仍然处于焦点。
- 单击"撤消视图"中的鼠标。
oops .. currentIndexchanged((来自撤消视图的信号可以先发送,或可以先发送来自qlineit的信号。
它总是不同的..
如果首先发送了来自QlineIt的信号 - 它可以正常工作。变化的历史不会丢失。
我想首先调用Enter/Blur和其他更改(不在历史记录视图中(。可能我可以使用qtimer :: singleshot((来延迟发射视图信号。但是不是curentIndexchanged((,因为此信号与用户交互以及撤消堆栈进行编程更新时发出。我们无法确定谁进行更改 - 用户或应用程序。
我尝试了什么?
拦截鼠标点击:
myUndoView::mousePressEvent(QMouseEvent *event)
{
event->ignore();
qDebug() << "catched!";
}
,但有时会失去点击。在列表项目的底部(在字母下(是将单击到该项目的区域。这可能是一个QT错误,在我的环境中发现:Debian,Mate,GTK QT风格。
我想,我可以将另一个透明的小部件放在列表上,并获得点击的坐标并使用它:
http://doc.qt.io/qt-5/qabstractitemview.html#indexat
获取所选索引。
,还是我错了?也许有一种更简单的方法?
如何使它正确?
我将尝试在焦点编辑时尝试阻止列表模型信号。
让我们有这样的事件过滤器:
class EventFilter : public QObject
{
Q_OBJECT
public:
EventFilter(QObject * model) : _model(model){}
bool eventFilter(QObject *watched, QEvent *event);
private:
QObject * _model;
};
将列表模型作为QObject
指针的私人引用,在构造函数参数中传递。
过滤器实现:
bool EventFilter::eventFilter(QObject *watched, QEvent *event)
{
if(event->type() == QEvent::FocusIn)
{
_model->blockSignals(true);
}
return false;
}
在窗口类中保留对过滤器实例的引用(在我的示例中,Form
(,以及列表模型实例参考:
private:
EventFilter * filter;
QAbstractListModel * model;
必须在Form
构造函数中实例化并安装在行编辑中(不要忘记在destructor中删除其(:
filter = new EventFilter(model); //the model is passed to the filter in construction
ui->lineEdit->installEventFilter(filter);
此时,当行编辑获得焦点时,模型事件将被阻止。要解锁它们,请使用行编辑editingFinished
插槽:
void Form::on_lineEdit_editingFinished()
{
model->blockSignals(false);
}