Home  >  Article  >  Backend Development  >  Implementing QML's TreeView Model using C (1)_PHP Tutorial

Implementing QML's TreeView Model using C (1)_PHP Tutorial

WBOY
WBOYOriginal
2016-07-12 08:54:161248browse

Use C to implement QML’s TreeView Model (1)

Data access components in QML such as ListView, TableView, and GridView usually use ListModel as the data provider. This application has considerable limitations. For example, the local file system cannot be accessed and the traditional SQL database cannot be connected, so data access is usually achieved through C, and data display and editing are performed through QML. Commonly used data model components include QAbstractItemModel, QAbstractTableModel, QSQLTableModel, etc. . All advanced Model components inherit from QAbstractItemModel. As long as you understand the interface functions and operating mechanism of QAbstractItemModel, you can understand the implementation of QT's Model/View mechanism.
QAbstractItemModel is an abstract class. To instantiate QAbstractItemModel, you must inherit and implement at least the following 5 methods:

int rowCount(const QModelIndex &parent=QModelIndex()) const;
int columnCount(const QModelIndex &parent=QModelIndex()) const;
QModelIndex index(int ​​row, int column, const QModelIndex &parent=QModelIndex()) const;
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;
QModelIndex parent(const QModelIndex &child) const;
Different from the QWidget component, in the QML data model, data access is not done through columns (Column), but through Roles, for example:

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>TableView{<br /> </li><li>id:tableView1<br /></li><li>anchors.fill: parent<br /></li><li>TableViewColumn{<br /></li><li>width:50<br /></li><li>title:""<br /></li><li>role:"tagging" </li><li>}<br /></li><li><br /></li><li>TableViewColumn{<br /></li><li>width:80<br /></li><li>title:"操作"<br /></li><li>role:"name" </li><li>} </li><li>} </li></ol>
TableViewColumn is the column definition of TableView. TableViewColumn obtains data from the model through the role attribute definition. TableView will obtain the roles available to the model by calling the roleNames() method of the model. Therefore, in addition to the five virtual functions that must be implemented, roleNames() must also be re-implemented to tell the View which roles are available. The prototype of roleNames() is as follows:


<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>QHash<int,QByteArray> roleNames() const; </li></ol>



The following is a complete Model class definition:

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>classSqlMenuEntry:public QAbstractItemModel,public QQmlParserStatus<br /> </li><li>{<br /></li><li>Q_OBJECT<br /></li><li>public:<br /></li><li>explicit SqlMenuEntry(QObject *parent=0);<br /></li><li>~SqlMenuEntry();<br /></li><li>enum MenuEntryRoles{idRole=Qt::UserRole+1,nameRole,defaultEntryRole,customEntryRole,iconRole,iconHoverRole};<br /></li><li>int rowCount(const QModelIndex &parent=QModelIndex()) const;<br /></li><li>int columnCount(const QModelIndex &parent=QModelIndex()) const;<br /></li><li>QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const;<br /></li><li>QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;<br /></li><li>QModelIndex parent(const QModelIndex &child) const;<br /></li><li>QHash<int,QByteArray>roleNames() const;<br /></li><li>private:<br /></li><li>QHash<int,QByteArray> mRoleNames;<br /></li><li> QList<QHash<int,QVariant>> mRecords; //真正的数据保存在这里,QList只能保存二维数据没办法保存树状节点,这里仅仅是例子<br /></li><li>};<br /></li><li><br /></li><li></li></ol>
The implementation of roleNames() is quite simple:

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>QHash<int, QByteArray> SqlMenuEntry::roleNames() const<br /> </li><li>{<br /></li><li>return mRoleNames;<br /></li><li>} </li></ol>
mRoleNames can be initialized in the class constructor:

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>SqlMenuEntry::SqlMenuEntry(QObject *parent)<br /> </li><li>:QAbstractItemModel(parent)<br /></li><li>{<br /></li><li>mRoleNames[nameRole] = "name";<br /></li><li>mRoleNames[idRole] = "menuid";<br /></li><li>mRoleNames[iconRole] = "icon";<br /></li><li>mRoleNames[defaultEntryRole] = "default";<br /></li><li>mRoleNames[iconHoverRole] = "iconHover";<br /></li><li>} </li></ol>
In QML, you can pass "name", "menuid", "icon" accesses data:

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>ListView{<br /> </li><li>model:MenuEntryModel{ }<br /></li><li>delegate:Item{<br /></li><li>Column{<br /></li><li>Text{text:name}<br /></li><li> Text{text:icon}<br /></li><li>}<br /></li><li>}<br /></li><li>} </li></ol>
If you only provide data for a two-dimensional table, you can simply implement data supply to the View view based on the names of the above interface functions, among which:


<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>int SqlMenuEntry::rowCount(const QModelIndex &parent) const<br /> </li><li>{<br /></li><li> return mRecords.size();</li><li><br /></li><li>} </li><li>int SqlMenuEntry::columnCount(const QModelIndex &parent) const </li><li>{ </li><li> return 1;  //QML不使用列获取数据,默认返回一列,不返回1例的话,View控件会认为表是空表,不获取数据 </li><li>} </li><li>QModelIndex SqlMenuEntry::index(int row, int column, const QModelIndex &parent) const </li><li>{ </li><li>  if((row >= 0)&&(row < mRecords.size())) </li><li>  { </li><li>    return createIndex(row,column); </li><li>  } </li><li>  return QModelIndex();  //返回一个无效的空索引 </li><li>} </li><li>QModelIndex SqlMenuEntry::parent(const QModelIndex &child) const </li><li>{ </li><li>  return QModelIndex(); //二维表中的行没有parent节点 </li><li>} </li><li>QVariant SqlMenuEntry::data(const QModelIndex &index, int role) const </li><li>{ </li><li>  if(index.isValid) </li><li>  { </li><li>   return mRecords[index.row()][role]; </li><li>  } </li><li>} </li></ol>



The data in mRecords can be generated on demand, such as obtained from the database server through the QSqlQuery component, to obtain added data:

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li> QHash<int,QVariant> row;<br /> </li><li>row[nameRole] = "name1";<br /></li><li>row[iconRole] = "icon1";<br /></li><li>mRecords.append(row); </li></ol>
The implemented model class can be registered through

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>qmlRegisterType<SqlMenuEntry>("com.limutech.tv",1,0,"MenuEntryModel");</li></ol>
. The registered class can generate an instance in QML:

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li> import com.limutech.tv 1.0<br /> </li><li>MenuEntryModel{<br /></li><li>id:menuEntryModel<br /></li><li>}<br /></li><li>ListView{<br /></li><li>model:menuEntryModel<br /></li><li>...<br /></li><li>} </li></ol>
The process for the View component to obtain data is roughly as follows:
1. View calls rowCount(constQModelIndex &parent) and passes an empty parent to get the number of rows of the root node;
2. View calls columnCount(const QModelIndex &parent) and passes an empty parent to get the number of columns of the root node;
3. View calls index(int ​​row, int column, const QModelIndex &parent) for each row and column enumeration. The row number, column number and empty parent get the root node QModelIndex;
4. Continue to use the returned modelIndex as the parent to get the rowCount and columnCount of each row. If it is greater than 0, the node has child nodes;
5. Call roleNames to return the available role list
6. With the returned modelIndex and role as parameters, call data to obtain the data and use the corresponding delegate to display it
Therefore, to display a tree list, you need to perform the two-dimensional table model Improve, handle the situation when parent is not empty, and at the same time, the model should be able to store tree-like data. In the next section, I will continue to share the implementation of the hierarchical model and some implementations involving data modification.








www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/1120299.htmlTechArticleUsing C to implement QML’s TreeView Model (1) Data access components in QML such as ListView, TableView, and GridView are commonly used As a data provider, ListModel has considerable limitations in its application...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn