Qt Learning Path (45): One of the custom model 2010-01-17 23:50:05 Tags: c + + tutorial Learn qt Tutorial qt original works, allow reproduced, please be sure to use hyperlinks in the form of the original source of the article, author information and this statement. Otherwise, the legal liability will be investigated. In front of http://devbean.blog.51cto.com/448512/267435 we talked about some of the predefined model provided by QT. However, in the face of changing demand, the model is far from meeting our needs. In addition, for the framework of QT, model is the first choice to meet the needs of most functions, that is to say, some of the features of this model you will never use, but also with it, the result is not very efficient. So, we also have to be able to customize the model.
Before we actually complete the custom model, let's look at a few key concepts in QT's Model-view architecture. Each data element in a model has a model index. This index indicates the location of the data in the model, such as rows, columns, and so on. This is the qmodelindex we've talked about before. Each data element also has a set of attribute values, called roles (roles). This property value is not the content of the data, but its properties, for example, whether the data is used to show the data or to display the column header. Therefore, this set of attribute values is actually defined as an enum of Qt, which is more common with Qt::D isplayrole and Qt::editrole, plus qt::tooltiprole, Qt::statustiprole, and QT: Whatsthisrole and so on. Also, some properties are used to describe basic presentation properties, such as Qt::fontrole, Qt::textalignmentrole, Qt::textcolorrole, Qt::backgroundcolorrole, and so on.
For the list model, a single line number is required to locate one of the data, and the line number can be accessed through the Qmodelindex::row () function, which requires two values for the table model: row and column numbers, These two values can be accessed through both functions Qmodelindex::row () and Qmodelindex::column (). In addition, for the tree model, the parent node of this element can be used for positioning. In fact, not only the tree model, but also the elements of the list model and table model have their own parent nodes, except for the list model and the table model, the parent nodes of their elements are the same, and point to an illegal qmodelindex. For all model, this parent node can be accessed through Qmodelindex::p arent () function. This means that each model item has its own role data, 0, one, or more child nodes. Since each element has its own child elements, they can be traversed by recursive algorithms, just like the tree traversal in a data structure. For a description of the parent node, see this diagram (from C + + GUI programming with QT4, 2nd Edition):
Let's look at a simple example to see how to implement a custom model. This example comes from the C + + GUI programming with QT4, 2nd Edition. First describe the requirements. What we're going to do here is a table similar to the currency exchange rate tables. Perhaps you will think, this is a very simple realization, directly with Qtablewidget is not OK. Indeed, it is convenient to use qtablewidget directly. However, consider a table of exchange rates that contains 100 currencies. Obviously, this is a two-dimensional table, and, for each currency, you need to give the exchange rate relative to the other 100 currencies (here, we have our own exchange rate also included, but this exchange rate is always 1.0000). So, this table has to have a 100 x = 10,000 data items. Now we're asking for less storage space. So we think that if our data is not the data displayed, but the exchange rate of the currency relative to the dollar, then the exchange rate of the other currencies can be calculated based on this exchange rate. For example, I store the renminbi relative to the U.S. dollar, the yen relative to the dollar, then the renminbi relative to the yen as long as the exchange rate can be obtained. I do not need to store 10,000 data items, as long as the storage of 100 is enough. So, we have to implement a model for ourselves. Currencymodel is such a model. Its underlying data uses a qmap<qstring, double> type of data, as key QString is the currency name, as value double is the exchange rate of this currency against the dollar. Then we look at the code:. H class Currencymodel:public Qabstracttablemodel
{
Public
Currencymodel (Qobject *parent = 0);
void Setcurrencymap (const qmap<qstring, double> &map);
int RowCount (const qmodelindex &parent) const;
int ColumnCount (const qmodelindex &parent) const;
Qvariant data (const QMODELINDEX &index, int role) const;
qvariant headerdata (int section, qt::orientation Orientation, int role) const;
Private
QString Currencyat (int offset) const;
Qmap<qstring, double> Currencymap;
}; . cpp Currencymodel::currencymodel (Qobject *parent)
: Qabstracttablemodel (parent)
{
}
int Currencymodel::rowcount (const QMODELINDEX & Parent) const
{
return Currencymap.count ();
}
int Currencymodel::columncount (const QMODELINDEX & Parent) const
{
return Currencymap.count ();
}
Qvariant Currencymodel::d ata (const qmodelindex &index, int role) const
{
if (!index.isvalid ())
return Qvariant ();
if (role = = Qt::textalignmentrole) {
return Int (Qt::alignright | Qt::alignvcenter);
} else if (role = = Qt::D isplayrole) {
QString rowcurrency = Currencyat (Index.row ());
QString columncurrency = Currencyat (Index.column ());
if (Currencymap.value (rowcurrency) = = 0.0)
Return "# # #";
Double amount = Currencymap.value (columncurrency)/Currencymap.value (rowcurrency);
Return QString ("%1"). Arg (amount, 0, ' F ', 4);
}
return Qvariant ();
}
qvariant currencymodel::headerdata (int section, qt::orientation Orientation, int role) const
{
if (Role! = Qt::D isplayrole)