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

Posted

技术标签:

【中文标题】Wt - 如何从 WTableView 中检索选定的记录?【英文标题】:Wt - How to retrieve selected record from WTableView? 【发布时间】:2015-01-30 13:21:17 【问题描述】:

我正在学习 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 的成员 Model 类型为 Wt::Dbo::QueryModel。但是,当它被分配给相同类型的其他变量时,该变量不会得到它。为什么?

有人能指点我吗?

编辑 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】:

天哪,我终于自己搞定了。

正确的做法是:

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

【讨论】:

以上是关于Wt - 如何从 WTableView 中检索选定的记录?的主要内容,如果未能解决你的问题,请参考以下文章

WTableView 中的 QueryModel:请举例说明如何添加一行并用刚刚创建的新记录填充它

如何从 QGraphicsView 中检索选定区域?

如何从 DataTables 中的选定数据中获取数据

从.net(C#)中的Webbrowser控件中检索选定的文本

插入 WStandardItemModel 太慢了

从 python 中的 PYQT5 QListview 获取选定文件的文件名