代码之家  ›  专栏  ›  技术社区  ›  Bull

Wt-如何从WTableView中检索所选记录?

  •  0
  • Bull  · 技术社区  · 10 年前

    我正在学习Web Toolkit(Wt,又名“Witty”)的基础。现在我正在与WTableViews和QueryModels作斗争。我无法检索从中选择的记录。

    我将此表TableTag定义为:

    class TableTag
    {
    public:
        static const unsigned int tableVersion = 1;
        std::string name;
    
        TableTag();
        ~TableTag();
        static void initTableRecords(Wt::Dbo::Session &_session);
    
        template<class Action>
        void persist(Action &_action)
        {
            Wt::Dbo::field(_action, name, "Name");
    
            //Wt::Dbo::hasMany(_action, tablePosts, Wt::Dbo::ManyToMany, "Post");
        }
    };
    typedef Wt::Dbo::collection< Wt::Dbo::ptr<TableTag> > TableTags;
    

    我这样表现:

    DDBBApp::DDBBApp(const WEnvironment& _env) : WApplication(_env),
        ddbbBackend_(DDBBApp::DDBB_DATA_NAME)
    {
        DDBBApp::setDDBBBackendAndSession(ddbbBackend_,ddbbSession_);
        ctrNotice_ = new WText("Notice text"); //Informative text
    
        //QueryModel    
        Wt::Dbo::QueryModel< Wt::Dbo::ptr<TableTag> > * qmTags1 = new Wt::Dbo::QueryModel< Wt::Dbo::ptr<TableTag> >();
        qmTags1->setQuery(ddbbSession_.find<TableTag>());
        qmTags1->addAllFieldsAsColumns();
    
        //WTableView    
        ctrGridTags_ = new WTableView();
        ctrGridTags_->setModel(qmTags1);
        ctrGridTags_->setSelectionMode(Wt::SelectionMode::SingleSelection);
        this->root()->addWidget(ctrGridTags_);
        this->root()->addWidget(new WBreak);
    
        //Info text
        this->root()->addWidget(ctrNotice_);
    
        //Conection SIGNAL - SLOT
        ctrGridTags_->selectionChanged().connect(this, &DDBBApp::onSelectionChanged);
    }
    

    我想检索用户选择的记录:

    void DDBBApp::onSelectionChanged()
    {
        WString str("Select done: ");
    
        WModelIndexSet indexSet_Tags = ctrGridTags_->selectedIndexes();
        for (WModelIndexSet::iterator index_iterator = indexSet_Tags.begin(); index_iterator != indexSet_Tags.end(); ++index_iterator)
        {
            //Here I get the idx of the record selected in WTableView
            WModelIndex index = *index_iterator;
            str += WString(std::to_string(index.row()));
    
            boost::any data = ctrGridTags_->model()->data(index);
            if (data.type() == typeid(__int64))
            {
                //Here I get the Id of record
                __int64 dataint64 = boost::any_cast<__int64>(data);
                str += " " + WString(std::to_string(dataint64));
            }
            else
            {
                std::string dataTypeName(data.type().name());
                str += " (" + dataTypeName + ")";
            }
    
            //THIS IS THE PROBLEMATIC SECTION
            Wt::WAbstractItemModel * aim = ctrGridTags_->model(); //OK but it's not specifically related to TableTags (it's general)
            Wt::Dbo::QueryModel< Wt::Dbo::ptr<TableTag> > qmtt1(aim); //NULL ¿?
    
            Wt::Dbo::QueryModel< Wt::Dbo::ptr<TableTag> > queryModel = ctrGridTags_->model(); //NULL too ¿?
    
            Wt::Dbo::QueryModel<Wt::Dbo::ptr<TableTag>> modelus = static_cast<Wt::Dbo::QueryModel< Wt::Dbo::ptr<TableTag> >> (ctrGridTags_->model()); //NULL... no way :-(          
    
                                  v-- error due to null value (qmtt1, queryModel, modelus) 
            std::string tagName = queryModel.resultRow(index.row()).get()->name;
            str += " " + tagName ;
        }
    
        ctrNotice_->setText(str);
    }
    

    我认为代码足够自动描述。我找到的最清晰的参考是: How to get at underlying data in a WTableView based on a QueryModel? 。如果按照建议进行尝试,会出现几个编译错误。

    调试时,我看到WTableView的成员模型类型为Wt::Dbo::QueryModel<Wt::Dbo::ptr>。但是,当它被分配给同一类型的其他变量时,那个变量就不能得到它。为什么?

    谁能给我指正确的路吗?

    编辑1

    我指出了一些额外的细节:

    我的代码包括以下标题:

    #include <Wt/Dbo/Dbo>
    #include <Wt/Dbo/Backend/Sqlite3>
    #include <Wt/Dbo/Query>
    #include <Wt/Dbo/QueryModel>
    #include <Wt/Dbo/SqlTraits>
    #include <Wt/Dbo/Types>
    #include <Wt/Dbo/WtSqlTraits>
    

    如果我尝试这种方式(类似于Koen提出的方式):

    Wt::Dbo::QueryModel<TableTag> *modelKoen = dynamic_cast<Wt::Dbo::QueryModel<TableTag> *> (ctrGridTags_->model());
    

    我收到以下编译错误:

    C:\Opt\Wt 3.3.3 msvs2013 x64\include\Wt/Dbo/SqlTraits_impl.h(50): error C2039: 'read' : is not a member of 'Wt::Dbo::sql_value_traits<Result,void>'
              with
              [
                  Result=TableTag
              ]
    ***
    *** NOT TRANSLATED FROM SPANISH ***
    ***
              C:\Opt\Wt 3.3.3 msvs2013 x64\include\Wt/Dbo/SqlTraits_impl.h(48) : durante la compilación de la función miembro de plantilla de clase 'TableTag Wt::Dbo::query_result_traits<Result>::load(Wt::Dbo::Session &,Wt::Dbo::SqlStatement &,int &)'
              with
              [
                  Result=TableTag
              ]
              C:\Opt\Wt 3.3.3 msvs2013 x64\include\Wt/Dbo/collection_impl.h(186) : vea la referencia a la creación de instancias de plantilla de función 'TableTag Wt::Dbo::query_result_traits<Result>::load(Wt::Dbo::Session &,Wt::Dbo::SqlStatement &,int &)' que se está compilando
              with
              [
                  Result=TableTag
              ]
              C:\Opt\Wt 3.3.3 msvs2013 x64\include\Wt/Dbo/SqlTraits_impl.h(27) : durante la compilación de la función miembro de plantilla de clase 'void Wt::Dbo::query_result_traits<Result>::getFields(Wt::Dbo::Session &,std::vector<std::string,std::allocator<_Ty>> *,std::vector<Wt::Dbo::FieldInfo,std::allocator<Wt::Dbo::FieldInfo>> &)'
              with
              [
                  Result=TableTag
      ,            _Ty=std::string
              ]
              C:\Opt\Wt 3.3.3 msvs2013 x64\include\Wt/Dbo/Query_impl.h(106) : vea la referencia a la creación de instancias de plantilla de función 'void Wt::Dbo::query_result_traits<Result>::getFields(Wt::Dbo::Session &,std::vector<std::string,std::allocator<_Ty>> *,std::vector<Wt::Dbo::FieldInfo,std::allocator<Wt::Dbo::FieldInfo>> &)' que se está compilando
              with
              [
                  Result=TableTag
      ,            _Ty=std::string
              ]
              C:\Opt\Wt 3.3.3 msvs2013 x64\include\Wt/Dbo/Query_impl.h(102) : durante la compilación de la función miembro de plantilla de clase 'std::vector<Wt::Dbo::FieldInfo,std::allocator<_Ty>> Wt::Dbo::Impl::QueryBase<Result>::fields(void) const'
              with
              [
                  _Ty=Wt::Dbo::FieldInfo
      ,            Result=TableTag
              ]
              C:\Opt\Wt 3.3.3 msvs2013 x64\include\Wt/Dbo/Query_impl.h(133) : vea la referencia a la creación de instancias de plantilla de función 'std::vector<Wt::Dbo::FieldInfo,std::allocator<_Ty>> Wt::Dbo::Impl::QueryBase<Result>::fields(void) const' que se está compilando
              with
              [
                  _Ty=Wt::Dbo::FieldInfo
      ,            Result=TableTag
              ]
              C:\Opt\Wt 3.3.3 msvs2013 x64\include\Wt/Dbo/Query_impl.h(124) : durante la compilación de la función miembro de plantilla de clase 'std::pair<Wt::Dbo::SqlStatement *,Wt::Dbo::SqlStatement *> Wt::Dbo::Impl::QueryBase<Result>::statements(const std::string &,const std::string &,const std::string &,int,int) const'
              with
              [
                  Result=TableTag
              ]
              C:\Opt\Wt 3.3.3 msvs2013 x64\include\Wt/Dbo/Query_impl.h(483) : vea la referencia a la creación de instancias de plantilla de función 'std::pair<Wt::Dbo::SqlStatement *,Wt::Dbo::SqlStatement *> Wt::Dbo::Impl::QueryBase<Result>::statements(const std::string &,const std::string &,const std::string &,int,int) const' que se está compilando
              with
              [
                  Result=TableTag
              ]
              C:\Opt\Wt 3.3.3 msvs2013 x64\include\Wt/Dbo/QueryModel_impl.h(137) : durante la compilación de la función miembro de plantilla de clase 'void Wt::Dbo::QueryModel<TableTag>::setCurrentRow(int) const'
              C:\Opt\Wt 3.3.3 msvs2013 x64\include\Wt/Dbo/QueryModel_impl.h(127) : vea la referencia a la creación de instancias de plantilla de función 'void Wt::Dbo::QueryModel<TableTag>::setCurrentRow(int) const' que se está compilando
              C:\Opt\Wt 3.3.3 msvs2013 x64\include\Wt/Dbo/QueryModel_impl.h(126) : durante la compilación de la función miembro de plantilla de clase 'boost::any Wt::Dbo::QueryModel<TableTag>::data(const Wt::WModelIndex &,int) const'
    

    据我在互联网上看到的,常见的错误是

    'read' : is not a member of 'Wt::Dbo::sql_value_traits<long,void>  
    'read' : is not a member of 'Wt::Dbo::sql_value_traits<string,void> 
    

    等等。将它们与我的进行比较

    'read' : is not a member of 'Wt::Dbo::sql_value_traits<Result,void>
    

    通常解决这些问题,包括标题

    #include <Wt/Dbo/SqlTraits
    #include <Wt/Dbo/WtSqlTraits>
    

    但对我来说不是。

    有什么建议吗?

    1 回复  |  直到 10 年前
        1
  •  1
  •   Bull    10 年前

    天啊,我终于自己拿到了。

    正确的方法是:

    Wt::Dbo::QueryModel< Wt::Dbo::ptr<TableTag> > * qmTags = static_cast<Wt::Dbo::QueryModel< Wt::Dbo::ptr<TableTag> > *>(ctrGridTags_->model());
    

    而不是:

    Wt::Dbo::QueryModel<Wt::Dbo::ptr<TableTag>> modelus = static_cast<Wt::Dbo::QueryModel< Wt::Dbo::ptr<TableTag> >> (ctrGridTags_->model());
    

    生成的工作代码如下:

    void DDBBApp::onSelectionChanged()
    {
        WString str("Select done: ");
    
        WModelIndexSet indexSet_Tags = ctrGridTags_->selectedIndexes();
        for (WModelIndexSet::iterator index_iterator = indexSet_Tags.begin(); index_iterator != indexSet_Tags.end(); ++index_iterator)
        {
            WModelIndex index = *index_iterator;
            str += WString(std::to_string(index.row()));
    
            boost::any data = ctrGridTags_->model()->data(index);
            if (data.type() == typeid(int))
            {
                int dataInt = boost::any_cast<int>(data);
                str += " " + WString(std::to_string(dataInt));
            }
            else if (data.type() == typeid(std::string))
            {
                std::string dataString = boost::any_cast<std::string>(data);
                str += " " + WString(dataString);
            }
            else if (data.type() == typeid(long))
            {
                long dataLong = boost::any_cast<long>(data);
                str += " " + WString(std::to_string(dataLong));
            }
            else if (data.type() == typeid(__int64))
            {
                __int64 dataint64 = boost::any_cast<__int64>(data);
                str += " " + WString(std::to_string(dataint64));
            }
            else
            {
                std::string dataTypeName(data.type().name());
                str += " (" + dataTypeName + ")";
            }
    
            Wt::Dbo::QueryModel< Wt::Dbo::ptr<TableTag> > * qmTags = static_cast<Wt::Dbo::QueryModel< Wt::Dbo::ptr<TableTag> > *>(ctrGridTags_->model());
            std::string tagName = qmTags->resultRow(index.row()).get()->name;
            str += " " + tagName;
        }
    
        ctrNotice_->setText(str);
    }