首页 > 解决方案 > 对异步运行并发出信号的命令使用撤消堆栈

问题描述

我有一个继承自的命令QUndoCommand

class ImportEntityCommand : public QUndoCommand
{
    // ...

private:
    QString m_importedEntityName;
    Importer *m_importer;
    // ...
}

redo方法启动一个 QProcess:

void ImportEntityCommand::redo()
{
    if (/* Import is already done before */) {
        // ...
    } else {
        // Import finish is handled by a slot
        m_importer->import(m_url);
    }
}

信号槽连接由命令构造函数组成:

ImportEntityCommand::ImportEntityCommand(EditorSceneItemModel *sceneModel, const QUrl &url) :
  , m_importer(new Importer(/* ... */))
{

    // Importer would start a QProcess which runs asynchronously and emits a signal
    // that's why I have to handle the signal by a slot
    QObject::connect(m_importer
                     , &Importer::importFinished
                     , this
                     , &ImportEntityCommand::handleImportFinish
                     );
}

进程发出的信号是这样处理的:

void ImportEntityCommand::handleImportFinish(const QString name)
{
    m_importedEntityName = name;
}

但是我在编译时收到这样的错误:

C:\Qt\Qt5.12.9\5.12.9\msvc2017_64\include\QtCore\qobject.h:250: 错误:C2664: 'QMetaObject::Connection QObject::connectImpl(const QObject *,void **,const QObject * ,void **,QtPrivate::QSlotObjectBase *,Qt::ConnectionType,const int *,const QMetaObject *)':无法将参数 3 从 'const ImportEntityCommand *' 转换为 'const QObject *'

错误点是:

无法将参数 3 从“const ImportEntityCommand *”转换为“const QObject *”

我想我继承了我的ImportEntityCommand类,QUndoCommand 而我的类又继承自QObject

问题

因此,出于某种原因,Qt 不允许我处理继承自QUndoCommand.

标签: c++qtsignalssignals-slotsqprocess

解决方案


我从 QUndoCommand 继承了我的 ImportEntityCommand 类,我猜它又从 QObject 继承。

QUndoCommand 不继承自 QObject 参见:

https://doc.qt.io/qt-5/qundocommand.html

例如,与 QWidget 相比,它确实继承自 QObject。

https://doc.qt.io/qt-5/qwidget.html

如果你想让你的导入器处理信号和槽,你可以从 QObject 继承:

class importer: public QObject
{
    Q_OBJECT
public:
    ...
private:
    ...
}

您可以连接到 lambda,例如:

QObject::connect(m_importer
                 , &Importer::importFinished
                 [&]() { this->handleImportFinish() }
                 );

推荐阅读