与撤消历史的麻烦(Qundostack,Qundoview等)

Troubles with undo history (QUndoStack, QUndoView and other)

本文关键字:Qundoview Qundostack 撤消 历史 麻烦      更新时间:2023-10-16

我有两个单独的线程。GUI的第一个线程,第二个用于应用程序数据的线程。

最初,我想使用Qundostack和Qundoview。

但是有一个问题 - 此视图直接与堆栈合作:

https://code.woboq.org/qt5/qtbase/src/widgets/widgets/qundoview.cpp.html#_zn10qundomodel20qundomodel20setstackcurrentstackcurrententindexerk11qmodelindex

在这种情况下,我有比赛状况。

为了解决这个问题,我使用qlistview和qabstractlistModel编写了自定义myundoview。现在,我使用排队连接的所有插槽,我在自定义视图模型中存储了"真实"撤消堆栈的轻量级副本。这是相同的大小和"真实"撤消堆栈元素的相同顺序。轻量级元素仅包含undo命令和文本的类型。

现在我还有另一个问题。我不责怪这个((

我有一个qlineedit,当我单击"输入键或丢失的焦点"时,会在值中发出信号。此值依次发送到具有"真实"撤消堆栈的对象(APP模型(。它有效。

,当我与撤消视图互动时,这也不起作用。重复一遍,我不是为此责备。Qundoview具有相同的行为。

逐步:

  1. 焦点中的Qlineit。
  2. 更改价值,仍然处于焦点。
  3. 单击"撤消视图"中的鼠标。

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);
}