Simple Widget Mapper
前置实例
- 无
实例位置
Qt_Offical_demo/widgets/itemviews/simplewidgetmodel
运行结果
- 点击按钮进行浏览
- 使用常规控件改变model的内容
主要使用类
- 一些标准控件
- QStandardItemModel
- QDataWidgetMapper
代码解析
从main
开始:
int main(int argc, char **argv)
{
QApplication app(argc, argv);
// Info 1
Window window;
window.show();
return app.exec();
}
Info 1:
跳转到Window类的构造函数:
Window::Window(QWidget *parent)
: QWidget(parent)
{
//Info 1.1
setupModel();
// 创建一些简单的控件
nameLabel = new QLabel(tr("Na&me:"));
nameEdit = new QLineEdit();
addressLabel = new QLabel(tr("&Address:"));
addressEdit = new QTextEdit();
ageLabel = new QLabel(tr("A&ge (in years):"));
ageSpinBox = new QSpinBox();
nextButton = new QPushButton(tr("&Next"));
previousButton = new QPushButton(tr("&Previous"));
// Info 1.2
nameLabel->setBuddy(nameEdit);
addressLabel->setBuddy(addressEdit);
ageLabel->setBuddy(ageSpinBox);
//! [Set up widgets]
//! [Set up the mapper]
// Info 1.3
mapper = new QDataWidgetMapper(this);
mapper->setModel(model);
mapper->addMapping(nameEdit, 0);
mapper->addMapping(addressEdit, 1);
mapper->addMapping(ageSpinBox, 2);
// Info 1.4
connect(previousButton, &QAbstractButton::clicked, mapper, &QDataWidgetMapper::toPrevious);
connect(nextButton, &QAbstractButton::clicked, mapper, &QDataWidgetMapper::toNext);
// Info 1.5
connect(mapper, &QDataWidgetMapper::currentIndexChanged, this, &Window::updateButtons);
//! [Set up the mapper]
//! [Set up the layout]
QGridLayout *layout = new QGridLayout();
layout->addWidget(nameLabel, 0, 0, 1, 1);
layout->addWidget(nameEdit, 0, 1, 1, 1);
layout->addWidget(previousButton, 0, 2, 1, 1);
layout->addWidget(addressLabel, 1, 0, 1, 1);
layout->addWidget(addressEdit, 1, 1, 2, 1);
layout->addWidget(nextButton, 1, 2, 1, 1);
layout->addWidget(ageLabel, 3, 0, 1, 1);
layout->addWidget(ageSpinBox, 3, 1, 1, 1);
setLayout(layout);
setWindowTitle(tr("Simple Widget Mapper"));
mapper->toFirst();
}
Info 1.1:
void Window::setupModel()
{
//创建一个StandardItemModel,呈表格状,5行3列
model = new QStandardItemModel(5, 3, this);
QStringList names;
names << "Alice" << "Bob" << "Carol" << "Donald" << "Emma";
QStringList addresses;
addresses << "<qt>123 Main Street<br/>Market Town</qt>"
<< "<qt>PO Box 32<br/>Mail Handling Service"
"<br/>Service City</qt>"
<< "<qt>The Lighthouse<br/>Remote Island</qt>"
<< "<qt>47338 Park Avenue<br/>Big City</qt>"
<< "<qt>Research Station<br/>Base Camp<br/>Big Mountain</qt>";
QStringList ages;
ages << "20" << "31" << "32" << "19" << "26";
//填充model
for (int row = 0; row < 5; ++row) {
//Info 1.1.1
QStandardItem *item = new QStandardItem(names[row]);
//Info 1.1.2
model->setItem(row, 0, item);
item = new QStandardItem(addresses[row]);
model->setItem(row, 1, item);
item = new QStandardItem(ages[row]);
model->setItem(row, 2, item);
}
}
Info 1.1.1:
QStandradItemModel需要使用QStandardItem作为内容进行填充。QStandardItem的构造函数有下面三种:
- QStandardItem();
- explicit QStandardItem(const QString &text); //就是填充要管理的内容
- QStandardItem(const QIcon &icon, const QString &text);
- explicit QStandardItem(int rows, int columns = 1);
Info 1.1.2:
函数的原型为void setItem(int row, int column, QStandardItem *item);
,作用是将QStandardItem填充到指定的行列位置。
Info 1.2:
语句nameLabel->setBuddy(nameEdit);
的意思是当使用nameLabel的快捷键的时,控件焦点会自动聚焦在nameEidt上面。
Info 1.3:
定义和使用QDataWidgetMapper类,将model映射到三个简单控件中。
mapper = new QDataWidgetMapper(this);
//设置要mapper的模型
mapper->setModel(model);
//addMappeing()的第一个参数是需要映射到的控件
//第二个参数是需要映射的内容区域,一般使用model的列号或行号来索引
mapper->addMapping(nameEdit, 0);
mapper->addMapping(addressEdit, 1);
mapper->addMapping(ageSpinBox, 2);
Info 1.4
注意这里出现的QDataWidgetMapper的两个槽函数和一个信号:
//槽函数:指向前一个映射
&QDataWidgetMapper::toPrevious
//槽函数:指向后一个映射
&QDataWidgetMapper::toNext
//信号:当映射的索引改变时
&QDataWidgetMapper::currentIndexChanged
Info 1.5
设置按钮是否可用
void Window::updateButtons(int row)
{
previousButton->setEnabled(row > 0);
nextButton->setEnabled(row < model->rowCount() - 1);
}
分析
- 本实例简单的讲解了如何使用Mapper将Model中的内容映射到控件中;
- 需要设置的是,映射是双向的,如果在LineEdit控件中对某一项进行修改的话,model中的内容也会被修改。如果有View去展示model的话,也会被同步修改。这就是使用Mapper的好处。
进阶实例
- SqlMapper Exampe