Qt调试错误(变量)无法访问

问题描述 投票:0回答:1

我遇到了一个运行时错误,在调试时将变量列为无法访问。关于这个主题还有其他帖子,但修复不适合我。

我使用QtCreator 4.5.1和Qt lib 5.10(Mingw32 5.3,MSVC14 x64,MSVC x64)

我已经按照disable pretty printers post的建议禁用了“加载系统GDB漂亮的打印机”。

失败代码的含义:

为了在我的解耦QtQuick2视图模型之间进行通信,我实现了一个简单版本的EventAgregator模式。

实施仍然缺少线程安全和清理不再存在的订户。但是它与我的错误无关。

错误的断点将被抛出和当前观察名单break point at error to be thrown watch list at breakpoint

相关代码文件:

qspinstartup.h

class QSpinStartup:QObject
{
public:
    QSpinStartup();

    bool loadQSpin(const QString dir, const QString startView="");
private:
    void registerQmlGui();
    void registerQmlViewModel();
    QQmlApplicationEngine engine;

    //constant viewmodel objects
    CodeEditorTab* codeEditor;
    VerificationTab* verificationEditor;
    QSpinMessageService msgService;
};

qspinstartup.cpp

QSpinStartup::QSpinStartup():QObject()
    ,verificationEditor(new VerificationTab(msgService,this))
    ,codeEditor(new CodeEditorTab(msgService,this))
    //,console(new ConsoleEditor(msgService,this))
{

    registerQmlGui();
    registerQmlViewModel();
    initPointerObjects();
    auto ctx = engine.rootContext();
    qSpinNullPtrCheck(ctx);
    PrintToConsole p("pri");
    msgService.publish<PrintToConsole>(p);
    ctx->setContextProperty("codeEditorVm",codeEditor);
}

bool QSpinStartup::loadQSpin(const QString dir,const QString startView)
{
    QDir ldir(dir);
    QString l = ldir.entryList(QStringList()<<startView,QDir::Files).first();
    qInfo()<<l;
    engine.load(QUrl(l.prepend("qrc:/")));
    bool isReady = engine.rootObjects().count()>0;
    qSpinSafeFail(!isReady,"Qml Application failed to start engine");

    return isReady;
}

void QSpinStartup::registerQmlGui()
{
    QSpinWorkSpace::Workspace::registerAsQml();

}

void QSpinStartup::registerQmlViewModel()
{
    VerificationTab::registerAsQml();
    CodeEditorTab::registerAsQml();
    ConsoleEditor::registerAsQml();
}

ieventbase.h

class IEventBase{
public:
    enum Types{ // <--simple way to give an object a type specifier
        PrintToConsole,
        CurrentDocumentChanged,
        CompilerOptions,
        SpinArgCommand
    };
    IEventBase(Types t):type(t){}
    const Types type;
};

qspinmessageservice.h

template<class T>
class ISubscriber{

public:
    virtual ~ISubscriber(){}
    virtual void executeSubscribed(T& event)=0;
};
class QSpinMessageService: public QObject{
    Q_OBJECT
    typedef QPointer<QObject> subscriber;
    typedef QVector<subscriber> EvAgrList;
    QHash<IEventBase::Types,EvAgrList> subs;
public:
    QSpinMessageService(QObject* parent=nullptr):QObject(parent)
      ,subs(QHash<IEventBase::Types,EvAgrList>()){}

    void subscribe(QObject *obj, IEventBase::Types key){
        if(!subs.contains(key)) // <-- this line cause my error
            subs[key]= EvAgrList();
        EvAgrList& list = subs[key];
        list<<subscriber(obj);
    }

    template<typename T>
    void publish(typename T::IEventBase execute){
        EvAgrList lSubs = subs[execute.type];
        for(int i=0; i<lSubs.count();i++){
            subscriber&q = lSubs[i];
            if(q.isNull()){
                lSubs.removeOne(q);
                --i;
                continue;
            }
            ISubscriber<T>* a = dynamic_cast<ISubscriber<T>*>(q.data());
            qDebug()<< q<<a;

            //ISubscriber<T>* s = dynamic_cast<ISubscriber<T>*>(q);
            a->executeSubscribed(static_cast<T&>(execute));
        }
    }
};
static QSpinMessageService dummy;

verificationtab.cpp(它是一个很大的类,所以我排除了不相关的部分)

VerificationTab::VerificationTab(QSpinMessageService &service, QObject *parent) :
    QSpinTab(parent,"Verification",QSpinTabType::Verification)
    ,msgService(service)
  ,m_stateProp(new StateSpaceProp(this)),m_stateSpec(new StateSpaceSpec(this))
  ,m_memoryUsage(new MemoryUsage(this)),m_settings(new VerificationSettings(this))
{
    msgService.subscribe(this,IEventBase::CurrentDocumentChanged); // <-- error call
//if the line above is commented out the application runs
}

Github repository of the full application

注意:

在将文件添加到主项目之前,我在单独的空项目中设计了QSpin MessageService。订阅方法适用于该项目。

知道怎么解决这个问题吗?

c++ qt c++11 runtime-error qtquick2
1个回答
0
投票

我终于找到了我的错误原因。尽管Debug Watch列表指出QSpinMessageService对象存在,但此时还没有进行过prberly初始化。为什么subscribe()甚至能够被访问超出了我目前的cpp技能。

修复:在qspinstartup.cpp中,构造函数需要更改如下。

qspinstartup.cpp

QSpinStartup::QSpinStartup():QObject()
{
    codeEditor = new CodeEditorTab(msgService,this);
    verificationEditor = new VerificationTab(&msgService,this);
    registerQmlGui();
    registerQmlViewModel();

    auto ctx = engine.rootContext();
    qSpinNullPtrCheck(ctx);
    PrintToConsole p("pri");
    msgService.publish<PrintToConsole>(p);
    ctx->setContextProperty("codeEditorVm",codeEditor);

}
© www.soinside.com 2019 - 2024. All rights reserved.