一、Item-Views(Model-Based)
1、TableView
1.1 TableView控件功能
(表格视图)是一个强大的控件,常用于显示和编辑二维表格数据。它提供了各种功能来管理和操作表格数据,包括:
1. 显示数据:TableView 可以根据数据模型显示表格数据。它以行和列的形式展示数据,每个单元格可以包含文本、图像或其他自定义的小部件。
2. 编辑数据:TableView 支持对表格数据进行编辑。用户可以在单元格内直接对数据进行修改,并根据定义的编辑规则来验证和更新数据。
3. 排序和过滤:TableView 提供了对表格数据的排序和过滤功能。用户可以对表格中的列进行排序,以按升序或降序排列数据。可以使用过滤器来根据指定条件过滤显示的数据。
4. 选择和多选:TableView 允许用户进行单元格的选择和多个单元格的多选。它支持各种选项模式,如单选、多选和连续选择。
5. 自定义单元格样式和外观:TableView 允许你通过自定义样式表(CSS)或其他绘制方法,对单元格的外观进行自定义。你可以设置不同的字体、颜色、背景和边框等,以满足特定的界面需求。
6. 表头和列操作:TableView 允许你对表头进行操作,如添加、删除和调整列宽。你可以通过拖拽表头来重新排序列,并支持对列进行排序指示符的显示。
7. 上下文菜单和自定义操作:TableView 支持右键点击单元格或行时显示上下文菜单。你可以自定义上下文菜单的内容,并将自定义操作与特定的单元格或行相关联。
8. 模型视图分离:TableView 将数据和界面分离,使用模型-视图架构。它使用数据模型来管理和操作底层数据,并将数据显示在视图上。这种分离使得你可以独立于数据而灵活地修改表格视图的外观和交互方式。
1.2TableView使用方法
1、 显示数据
可以通过创建QStandardItemModel类对象model来设置TableView要显示的内容,通过对model的修改来对TableView显示内容进行变换
注意:如果将model创建为局部变量,会导致TableView无法显示。原因是局部变量被系统自动回收后,与TableView绑定的model就不存在了,此时就相当与还未绑定model,当然就不显示任何内容。
//创建QStandardItemModel对象指针*model
QStandardItemModel *model = new QStandardItemModel();
//通过tableView的setModel来将model与tableView进行绑定
ui->tableView->setModel(model);
//设置tableView水平自适应
m_ui.tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
2. 编辑数据
设置表头标题
QStringList fields = line.split("\t"); // 假设数据以制表符分隔,line为QSring类型
model->setHorizontalHeaderLabels(fields); //设置列标题
//修改表头标题时会触发model实例的QStandardItemModel::headerDataChanged信号
设置表格单元值
//这里介绍两种设置单元格值
//第一种
//(row,column)为要设置的单元格行号和列号
//data 为QStandardItem对象
model->setItem(row,column,&data);
//第二种
//index为要设置单元格的坐标;
//通常用创建QModelIndex index = tableView->model()->index(row,column)
model->setData(index,&data)
//修改单元格值时会触发model实例的QStandardItemModel::dataChanged信号
3. 排序和过滤
4、选择与多选
单击一个单元格时,会触发tableView的QTableView::clicked(const QModelIndex& index)信号,index即为该单元格坐标。
5、自定义单元格样式和外观
6、表头和列操作
model->setColumnCount(column); //设置表格列数
model->setRowCount(rows);//设置表格行数
该操作不会触发model的dataChanged型号,可以通过以下方式进行手动触发
QModelIndex topLeft,bottomRight;
emit model->dataChanged(topLeft, bottomRight); //手动发送数据修改信号
7、上下文菜单和自定义操作
QMenu* m_pContextMenu; //TableView右键菜单指针
m_pContextMenu = new QMenu(this);
//添加动作及处理函数
m_pContextMenu->addAction("打开文件", this, &JxArcher_StudyDemo::slots_OpenFile);
m_pContextMenu->addAction("保存文件", this, &JxArcher_StudyDemo::slots_SaveFile);
8、其他
获取TableView数据
//获取TableView表头标题
for (int index = 0; index <m_pModel->columnCount(); ++index) {
sText += m_pModel->headerData(index, Qt::Horizontal,
Qt::DisplayRole).toString()+'\t';
}
sText += '\n';
//获取TableView数据
for (int row = 0; row < m_pModel->rowCount(); ++row) {
for (int col = 0; col < m_pModel->columnCount(); ++col) {
QModelIndex index = m_pModel->index(row, col);
QVariant data = m_pModel->data(index);
sText += data.toString() + "\t";
}
sText += "\n";
}
m_ui.plainTextEdit->setPlainText(sText);// 将内容设置给PlainTextEdi
打开文件选择对话框
//打开选择文件对话框
//将选择或新建文件名存储在filename
QString fileName = QFileDialog::getOpenFileName(
this,
tr("open a file."), //提示
"./", //路径
tr("sText(*.txt);;All files(*.*)")); //文件格式类型
do {
if (fileName.isEmpty()) {
//读取文件失败
QMessageBox::warning(this, "Warning!", "Failed to open the sText!");
break;
}
else;
QFile* file = new QFile(fileName); // 创建QFile对象
if (file->open(QIODevice::ReadWrite | QIODevice::Text) == 0) {
//打开文件失败
QMessageBox::warning(this, "Warning!", "打开文件失败!");
break;
}
else;
//释放资源
file->close();
delete(file);
} while (0);
2、ListView
ListView操作与TableView基本一致,其model类型为QStringListModel
QStringList stringList = { "data1","data2" };
QStringListModel *model = new QStringListModel();//创建model
model->setStringList(stringList); //设置model的内容
listView->setModel(model); //将model与listView绑定
二、对话框
1、自定义对话框
当对话框销毁时会发送QDialog::finished信号
setWindowTitle("SetColumnOrRow");//设置标题
setModal(true); // 设置为模态对话框
新窗口启动分为模态和非模态:
-
模态(Modal):模态指的是一种界面状态,当一个对话框或窗口是模态的时候,它会阻止用户与其他界面元素进行交互,直到处理完当前对话框或窗口。在模态状态下,用户只能与模态对话框或窗口进行交互,不能在其他地方进行操作,直到对话框或窗口被关闭或处理完成。模态对话框通常用于需要用户必须提供响应或完成特定任务的场景,如输入信息、确认操作或选择选项等。
-
非模态(Modeless):非模态指的是一种界面状态,允许用户与界面的其他元素进行交互,而不会阻止用户对其他界面的操作。非模态对话框或窗口可以同时存在于界面上,用户可以在不关闭对话框或窗口的情况下与其他元素进行交互。非模态对话框通常用于提供辅助、附加或可选择的功能,用户可以在不中断当前任务的情况下使用它们
dialog->exec();//以模态方式启动
dialog->show();//以非模态方式启动
//或者使用以下方式
dialog->setAttribute(Qt::WA_ShowModal, false); //设置对话框模式未非模态
三、其他
1、多线程
1.1 Thread
当线程函数为成员行数时,要传入实例指针
void MyClass::RUN(){
//创建新线程
thread th1(&MyClass::thread_Fuc, this[,param]);
th1.join();//主线程阻塞直到th1线程执行完成
th1.detach();//线程分离,主线程与th1线程执行顺序无关
}
需要注意的是,Qt的信号槽机制默认是在同一线程中执行的,如果你要在不同的线程中进行信号传递,需要使用Qt::QueuedConnection
连接模式,确保信号在目标线程的事件循环中被处理。
// 在接收信号的类中连接信号和槽,并使用 Qt::QueuedConnection 连接模式
QObject::connect(senderObject, SIGNAL(dataUpdated(QString)), receiverObject, SLOT(onDataUpdated(QString)), Qt::QueuedConnection);
1.2 QThread
使用QThread类创建多线程,需要编写QThread子类并改写其run()方法,并通过调用对象的start()方法运行该线程
创建QThread派生类
MyThread.h
#include <QThread>
Class MyThread : public QThread{
public:
void run() override;
}
MyThread.cpp
#include "MyThread.h"
void MyThread::run(){
//执行内容
}
使用
main.cpp
#include "MyThread.h"
int main(int argc, char* argv[]){
MyThread thread;
thread.start();
//QThread 默认为detach模式
//若要等待线程执行完成,可添加下面代码
//thread.wait();
}
2、数据库操作
数据库也可以通过TableView进行显示。要包含QtSql头文件。且在项目创建时也要选择sql模块,否则无法找到该头文件。
#include<QtSql>
2.1添加SQLite驱动,打开数据库
// 添加SQLite驱动
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
// 指定数据库文件路径和名称
db.setDatabaseName("database.db");
// 打开数据库
if (db.open() == 0) {
qDebug() << "无法打开数据库:" << db.lastError().text();
}
db.close(); // 关闭数据库连接
2.2对数据库继续操作
QString createString = "SQL语句";
QSqlQuery query(createString);
query.exec(); //执行SQL语句
通过参数优化查询语句,可以使SQl语句表达清晰、易懂。
QString updateQuery = "UPDATE employee SET name = :name, gender = :gender,\
height = :height,birthdate = :birthdate,hobbies = :hobbies,\
salary = :salary,residence = :residence\
WHERE emp_id = :emp_id;"; //创建带差数的SQl语句; :param代表参数
QSqlQuery query;
query.prepare(updateQuery);
//绑定参数
query.bindValue(":emp_id", m_ui.lineEdit->text());
query.bindValue(":name", m_ui.lineEdit_2->text());
query.bindValue(":gender", m_ui.lineEdit_3->text());
query.bindValue(":height", m_ui.lineEdit_4->text());
query.bindValue(":birthdate", m_ui.lineEdit_5->text());
query.bindValue(":hobbies", m_ui.lineEdit_6->text());
query.bindValue(":salary", m_ui.lineEdit_7->text());
query.bindValue(":residence", m_ui.lineEdit_8->text());
query.exec();//执行SQL语句
2.3数据库模型有QSqlQueryModel和QSqlTableModel数据模型
2.1QSqlQueryModel
QSqlQueryModel的创建与TableView的绑定
QSqlQueryModel *model = new QSqlQueryModel(this);//创建QSqlQueryModel模型
tableView->setModel(model); //绑定到tableView
QString queryString = "SELECT * FROM employee";
model->setQuery(queryString); //对通过查询结果model进行赋值
3、 QDataWidgetMapper的功能及使用
QDataWidgetMapper是Qt框架中的一个类,它用于实现数据模型和界面控件之间的映射。它的主要功能如下:
-
数据绑定:QDataWidgetMapper可以将数据模型中的数据绑定到界面控件上,实现数据的自动更新和显示。它支持将各种数据类型(如整型、浮点型、字符串等)和数据结构(如列表、表格等)映射到适当的控件上。
-
双向绑定:QDataWidgetMapper不仅可以将数据从模型映射到控件上,还可以将用户对控件的更改反映回数据模型中。这使用户在界面上的操作能够直接影响到数据模型,从而实现数据的双向同步。
-
多个控件映射:QDataWidgetMapper可以将多个控件映射到同一个数据模型中的不同字段或属性上。这样,在界面上修改一个控件的值时,其他映射的控件也会随之更新。
-
数据校验和转换:QDataWidgetMapper允许在数据模型和界面控件之间进行数据的校验和转换操作。可以自定义校验器和转换器,对输入的数据进行有效性验证和格式转换,以确保数据的一致性和正确性。
创建QDataWidgetMapper,并将lineEdit绑定与QSqlQueryModel对象绑定
QDataWidgetMapper *mapper = new QDataWidgetMapper(this);
mapper->setModel(model); // model为QSqlQueryModel对象,已在之前创建并填充数据
mapper->addMapping(ui.lineEdit, 0); // 将第0列与employeeId关联
mapper->addMapping(ui.lineEdit_2, 1); // 将第1列与name关联
mapper->addMapping(ui.lineEdit_3, 2); // 将第2列与gender关联
mapper->addMapping(ui.lineEdit_4, 3); // 将第3列与height关联
mapper->addMapping(ui.lineEdit_5, 4); // 将第4列与birthdata关联
mapper->addMapping(ui.lineEdit_6, 5); // 将第5列与hobbies关联
mapper->addMapping(ui.lineEdit_7, 6); // 将第6列与salary关联
QModelIndex currentModelIndex = pUi->tableView->currentIndex();
row = currentModelIndex.row(); //获取当前TableView选择中的行号
mapper->setCurrentIndex(row); // 设置对话框中编辑控件显示的内容