【问题标题】:Qt debug error (variable) not accessibleQt 调试错误(变量)不可访问
【发布时间】:2018-08-12 05:13:25
【问题描述】:

我遇到了运行时错误,在调试时将变量列为不可访问。关于这个主题还有其他帖子,但修复对我不起作用。

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

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

失败代码的意图:

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

实现仍然缺少线程安全和清理不再存在的订阅者。但是这与我的错误无关。

要抛出的错误断点和当前观察列表

相关代码文件:

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

注意:

在将文件添加到主项目之前,我在单独的空项目中设计了 QSpinMessageService。订阅方法在该项目中有效。

知道如何解决这个问题吗?

【问题讨论】:

    标签: c++ qt c++11 runtime-error qtquick2


    【解决方案1】:

    我终于找到了错误的原因。尽管 Debug Watch 列表表明 QSpinMessageService 对象存在,但此时它尚未正确初始化。 为什么 subscribe() 甚至可以被访问,超出了我目前的 cpp 技能。

    修复: 在 qspinstartup.cpp 中,construtor 需要更改如下。

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

    【讨论】:

      猜你喜欢
      • 2023-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-15
      • 1970-01-01
      • 2011-04-29
      • 1970-01-01
      • 2017-05-05
      相关资源
      最近更新 更多