Qt 6.2C++程序设计与桌面应用开发 思政教学课件 第7、8章 文件与数据库、模型视图结构_第1页
Qt 6.2C++程序设计与桌面应用开发 思政教学课件 第7、8章 文件与数据库、模型视图结构_第2页
Qt 6.2C++程序设计与桌面应用开发 思政教学课件 第7、8章 文件与数据库、模型视图结构_第3页
Qt 6.2C++程序设计与桌面应用开发 思政教学课件 第7、8章 文件与数据库、模型视图结构_第4页
Qt 6.2C++程序设计与桌面应用开发 思政教学课件 第7、8章 文件与数据库、模型视图结构_第5页
已阅读5页,还剩173页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Qt6.2/C++程序设计与桌面应用开发21世纪高等学校计算机类课程创新规划教材–微课视频版教材目录第1章初识Qt框架第2章Qt开发基础第3章界面设计组件第4章主框架窗口第5章对话框设计第6章事件系统第7章文件与数据库第8章模型/视图结构第9章图形绘制第10章多媒体编程第11章网络编程第12章进程与线程教材目录第7章文件与数据库7.1Qt文件系统7.2目录操作7.3文件操作7.4QtSQL概述7.5数据库操作7.1Qt文件系统Qt的文件系统主要用于处理外部设备、进程、文件等的输入与输出,以及对文件和目录操作。Qt文件系统的功能通过Qt的一些支持数据块读/写的输入/输出(I/O)类来实现。7.1.1文件系统类Qt的文件系统包含多个支持读/写数据块的设备。这里所说的“设备”,不是指平常所说的硬件设备,而是指软件设备,也就是像QFile、Qprocess等这样的文件I/O设备对象。下面是部分文件系统类及功能。在上述类中,其继承关系可以大致分为3种类型:一种是完全独立的类,比如QDir、QFileInfo、QImageReader和Qurl等,它们既无父类也无子类;第二种是只有一个父类而没有子类的类,比如QFileSystemWatcher、QSettings、QSocketNotifier、QTextDocument只有QObject一个父类,QDataStream、QTextStream只有QIODeviceBase一个父类;第三种是继承关系相对比较复杂的类,像QIODevice、QBuff、QFile等。7.1.2文件I/O设备Qt文件系统中的相关操作类,也称为文件I/O设备,都是从QIODevice类派生而来的,QIODevice类为这些I/O设备提供了一个基础的抽象接口。QIODevice类继承于QObject和QIODeviceBase类,如图7.1所示。该类是一个抽象类,不能直接实例化,一般是使用它所定义的接口,例如open()、read()和write()等,来实现与设备无关的相关I/O功能。在访问一个设备之前,需要首先打开该设备,并且必须指定正确的打开模式。QIODevice中的所有打开模式在其基类QIODeviceBase中定义,如表7.2所示。7.2目录操作在Qt中,使用QDir

和QTemporaryDir类的对象来进行目录操作。其中,QDir用于普通目录的操作,QTemporaryDir

用于临时目录的操作。7.2.1QDir类QDir类位于Qt的Core模块内,用于访问目录结构及其内容,可以操作路径名、访问路径和文件的相关信息以及操作低层的文件系统,还可以访问Qt的资源系统。下面是一段示例代码:上述代码的运行结果如下图所示。7.2.2QTemporaryDir类QTemporaryDir类用于创建、删除临时目录。使用QTemporaryDir类可以在系统临时目录,即QDir::tempPath目录下创建一个临时目录,临时目录名称以QCoreApplication::applicationName()函数的返回值为前缀,后加6个字符。临时目录可以设置为使用完后自动删除,即临时目录变量删除时,临时目录也删除。下面是一段简单的示例代码。该示例代码的运行结果如下图所示。图中上部分为资源管理器中的系统临时目录。7.2.3QFileInfo类在图7.2所示的示例程序中,使用了QFileInfo类来获取某个文件的信息。下面是使用QFileInfo成员函数的一段示例代码。上述示例代码的输出结果如下:7.2.4常用操作目录操作主要包括:新建、删除、重命名、查询和遍历等。1、新建使用QDir类的成员函数mkdir()或mkpath()来创建单层或多层目录。函数原型如下:

boolQDir::mkdir(constQString&dirName)const或

boolQDir::mkpath(constQString&dirPath)const例如,下面的语句QDirdir;dir.mkdir(“f:/qt”);将会在F盘的根目录下创建一个名为qt的新的子目录。而下面的语句QDirdir;dir.mkpath(“f:/qt1/qt2/demo”)则会在F盘的根目录下创建名为demo的子目录。若demo子目录的上一级目录不存在,则会依次创建其上一级目录。2、删除使用QDir类的成员函数rmdir()、rmpath()或removeRecursively()来删除目录。其中,rmdir()用于删除单层空目录;rmpath()用于删除多层空目录;removeRecursively()删除目录及其中的所有文件。例如,下面的语句:QDirdir;dir.rmdir(“f:/qt”);将会删除F盘根目录下的名为qt的空子目录。而下面的语句:QDirdir;dir.rmpath(“f:/qt1/qt2/demo”)则会删除F盘根目录下的名为demo的空子目录及其上一级目录中的空目录。而下面的语句:QDirdir(“f:/qt1/qt2/demo”);dir.removeRecursively()则会删除F盘根目录下的名为demo的目录及其中的所有内容(子目录和文件)。3、重命名使用QDir类的成员函数rename()来重命名目录。boolQDir::rename(constQString&oldName,constQString&newName)其中,参数oldName和newName分别表示目录的原名称和新名称。例如,下面的语句QDirdir;dir.rename(“f:/qt”,”f:/qt2”);将F盘根目录下的qt目录名称修改为qt2。4、属性查询目录的属性可以通过QDir类和QFileInfo类的成员函数进行查询。使用QDir类的成员函数isAbsolute()、isRelative()、isAbsolutePath()、isRelativePath()、isReadable()、isRoot()和isEmpty()来判断目录是绝对路径还是相对路径、是否可读、是否是根目录和是否为空,目录的大小、创建时间、修改时间等属性则需要通过QFileInfo类的成员函数来进行查询。5、遍历通过遍历目录可以获取该目录下的所有子目录和文件信息,使用QDir类的entryList()或entryInfoList()成员函数可以完成相应的操作。【例7.1】编写一个名为examp7_1的Qt应用程序,实现指定目录的遍历功能。(1)启动QtCreator集成开发环境,创建一个名为examp7_1的应用程序。该应用程序主窗口基于QWidget类。(2)在应用程序主窗口中添加两个控件,一个是QLineEdit对象lineEdit,另一个是QListWidget对象listWidget。lineEdit用于输入目录名称,listWidget用于显示目录下的信息。(3)为应用程序的Widget类添加成员函数showInfoList(),以及槽函数showDirs()和showSubDirs()。函数showInfoList()用于遍历指定的目录;槽函数showDirs()用于响应lineEdit对象的输入结束信号;槽函数showSubDirs()用于响应listWidget子项的双击信号。函数声明及实现代码如下:(4)在Widget类的构造函数中添加初始化代码。(5)构建并运行程序。7.3文件操作应用程序对文件的操作,主要包括文件的打开与关闭、信息的查询、内容的读写,以及重命名、移动与复制、删除等。这些功能通过Qt的文件I/O设备QFile、QSaveFile等来实现。7.3.1相关操作类实现Qt应用程序的文件操作功能,除了需要使用上面介绍的QDir、QFileInfo

等类之外,还可以使用QFile、QTextStream

和QDataStream

等类。1、QFile类QFile类提供了一个用于读/写文件的接口,可以用来读/写文本文件、二进制文件和Qt的资源文件。下面是一段使用QFile对象的示例代码,该示例代码打开用户选择的文本文件,并在文本编辑器显示。Qt的QTextStream

是以流方式操作文本文件的类。与QFile类相比,它提供了更为方便的接口来读写文本,可以操作QIODevice、QByteArray和QString。使用QTextStream的流操作符,可以方便地读/写单词、行和数字。对于生成的文本,QTextStream

还提供了字段填充、对齐和数字格式化的选项。QTextStream类的使用非常简单,下面是一段示例代码,该示例代码打开用户选择的文本文件,并在文本编辑器显示。3、QDataStream类QDataStream类实现了将QIODevice的二进制数据串行化。一个数据流就是一个二进制编码信息流,完全独立于主机的操作系统、CPU和字节顺序。数据流也可以读/写未编码的二进制数据。QDataStream类可以实现C++基本数据类型的串行化,比如char、short、int和char*等。下面是一段示例代码:7.3.2文件信息查询QFileInfo类提供了对文件进行操作时获得的文件相关属性信息,包括文件名、文件大小、创建时间、最后修改时间、最后访问时间,以及文件是否为目录、文件或符号链接和读写属性等。【例7.2】编写一个Qt应用程序,获取用户所选文件信息。(1)启动QtCreator集成开发环境,创建一个名为examp7_2的应用程序。该应用程序主窗口基于QWidget类。(2)双击widget.ui界面文件,打开QtDesigner设计工具,设计如图7.6所示的应用程序主窗口界面。界面中组件对象名称及类型请参见教材源码。(3)为主窗口中的“文件”和“获取文件信息”两个按钮添加clicked信号槽函数,并编写代码。如下所示。7.3.3文本文件读写文本文件是指以纯文本格式存储的文件,例如Windows的记事本文件。Qt提供了2种读写文本文件的方法,一种是使用QFile类的IODevice读写功能直接进行文件的读写,另一种是利用Qfile和QTextStream结合起来,用流(Stream)的方法进行文件读写。【例7.3】编写一个Qt应用程序,示例文本文件的读/写操作。(1)打开QtCreator集成开发环境,创建一个名为examp7_3的应用程序。该应用程序主窗口基于QMainWindow类。(2)双击mainwindow.ui界面文件,打开QtDesigner设计工具,设计应用程序主窗口界面及工具栏上的Action。如下图7.8所示。(3)为类MainWindow添加4个私有成员函数,来实现文本文件的打开和保存功能。声明代码如下:(4)编写4个私有成员代码,完成相应的文本文件读/写功能。如下所示。(5)为Action添加槽函数。如下所示。7.3.4二进制文件读写QDataStream类提供了基于QIODevice

的二进制数据的序列化。QDataStream既能够存取C++基本类型,如int、char、short等,也可以存取复杂的数据类型,例如自定义的类。【例7.4】编写一个Qt应用程序,示例二进制文件的读/写操作。(1)打开QtCreator集成开发环境,创建一个名为examp7_4的应用程序。主窗口基于QMainWindow类。(2)双击mainwindow.ui界面文件,打开QtDesigner设计工具,设计应用程序主窗口界面及工具栏上的Action。(3)编写上述Action的triggered信号槽函数代码,如下所示。(4)构建并运行程序。7.4QtSQL概述Qt的SQL模块提供对数据库编程的支持。Qt支持多种常见的数据库,如MySQL、Oracle、MSSQLServer、SQLite等。7.4.1QtSQL模块QtSQL模块包含包括多个类,可以实现数据库连接、SQL语句执行、数据获取与界面显示等功能。QtSQL模块中的类可以分为三个层次,即驱动层、SQL接口层和用户接口层。驱动层为具体的数据库和SQL接口层之间提供底层桥梁;SQL接口层提供了对数据库的访问支持;用户接口层提供数据从数据库到界面窗口部件的映射,使用Qt的模型/视图结构实现。QtSQL模块类所属层次及功能如下表所示:7.4.2QtSQL驱动QtSQL模块使用数据库驱动来与不同的数据库接口进行通信。Qt的SQL模型接口是独立于数据库的,所以所有数据库特定的代码都包含在了这些驱动中。Qt默认支持一些驱动,如表7.11所示。7.5数据库操作Qt应用程序中的数据库的操作,主要包括连接数据库、打开数据库、查询数据库、创建数据表、对数据表中的记录执行增/删/改/查操作等。7.5.1数据库的连接应用程序要与数据库进行交互,必须先创建并打开一个或多个数据库连接。在Qt中,数据库的连接、打开等操作通过QSqlDatabase类来实现。一般使用QSqlDatabase类的静态成员函数addDatabase()来创建数据库连接。该函数的原型如下:1、连接MySQL数据库Qt与MySQL数据库的连接,除了使用QMYSQL驱动之外,还需要使用QSqlDatabase的一些成员函数来设置数据库服务器主机名称、端口号、用户名、密码等连接参数。【例7.5】编写一个Qt的非GUI应用程序,实现与MySQL数据库的连接。(1)启动QtCreator集成开发环境,创建一个名为examp7_5的非GUI的Qt应用程序。(2)打开项目文件examp7_5.pro,在其中添加代码“QT+=sql”,引入QtSQL模块。(3)打开项目main.cpp文件,在其中添加如下代码:(4)构建并运行程序。输出结果如图7.14所示。从程序的输出结果可以看出,数据库没有被成功打开,主要原因是程序不能与名为localhost的MySQL数据库服务器连接。(5)启动本机的MySQL数据库服务器,并查看该服务器上的数据库。如图7.15所示。(6)再次运行程序,输出结果如图7.16所示。2、连接SQLite数据库Qt默认提供SQLite数据库驱动。SQLite是一种无需服务器、无需进行任何配置的数据库,它的所有数据表、索引等数据库元素全都存储在一个文件里,所以又被称为文件数据库。另外,SQLite还是一款可以跨平台使用的数据库,其数据库文件可以在不同平台之间随意复制。连接SQLite数据库非常简单,只需要使用Qt的QSQLITE驱动即可。需要注意的是,由于SQLite数据库是一种进程内的本地数据库,所以连接时不需要设置数据库名、用户名、密码、主机名和端口等连接参数。【例7.6】编写一个Qt的非GUI应用程序,实现与SQLite数据库的连接。(1)启动QtCreator集成开发环境,创建一个名为examp7_6的非GUI的Qt应用程序。(2)打开项目文件examp7_6.pro,在其中添加代码“QT+=sql”,引入QtSQL模块。(3)打开项目main.cpp文件,在其中添加如下代码:若在设置数据库名称时使用“:memory:”标识符,则说明这是建立在内存中的数据库,也就是说该数据库只在程序运行期间有效,等程序运行结束时就会将其销毁。如上述代码中的语句1所示。若在设置数据库名称时使用具体的数据库名称,则会在指定的位置创建数据库文件。如上述代码中的语句2所示。(4)构建并运行程序。输出结果如图7.17所示。3、连接MSAccess数据库Qt默认提供QODBC数据库驱动,如图7.13所示。可以使用该驱动来连接MSAccess数据库。【例7.7】编写一个Qt的非GUI应用程序,实现与MSAccess数据库的连接。(1)准备测试用的Access数据库。这里使用教材源码中的数据库文件chap07\examp7_7\studentDB.mdb。(2)注册数据源。首先打开如图7.18所示的Windows系统ODBC数据源管理工具,单击“添加”按钮,选择“MicrosoftAccessdriver(*.mdb,*.accdb)”数据源驱动程序,如图7.19所示。(3)启动QtCreator集成开发环境,创建一个名为examp7_7的非GUI的Qt应用程序。(4)打开项目文件examp7_7.pro,在其中添加代码“QT+=sql”,引入QtSQL模块。(5)打开项目main.cpp文件,在其中添加如下代码:(6)构建并运行程序。输出结果如图7.21所示。7.5.2数据库的操作使用Qt数据库驱动成功连接到相应的数据库后,就可以进行数据库的创建、数据表的创建、记录的添加等操作了。在Qt中,对数据库的操作通过QSqlQuery类实现,该类的部分成员函数及功能如表7.13所示。1、创建数据库调用QSqlQuery::exec()函数执行SQL命令“createdatabasedatabase_name”,即可创建一个MySQL数据库。【例7.8】修改例7.5中程序代码,使程序运行后新建一个名为qt_examp7_8db的MySQL数据库。(1)复制例7.5中的examp7_5项目,将其名称修改为examp7_8。(2)打开项目examp7_8的main.cpp文件,将其中的部分代码修改如下:(3)启动MySQL数据库服务器。(4)构建并运行程序。程序运行完成后,打开phpMyAdmin工具查看名为qt_examp7_8db的MySQL数据库是否创建成功。2、创建数据表调用QSqlQuery::exec()函数执行SQL命令

createtabletable_name…即可在打开的MySQL数据库中创建一张数据表。【例7.9】编写一个非GUI的Qt应用程序,程序运行后,在例7.8创建的名为qt_examp7_8db的数据库中新建一张名为student的数据表,表结构如图7.23所示。(1)复制例7.8中的examp7_8项目,将其名称修改为examp7_9。(2)打开项目examp7_9的main.cpp文件,将其中的部分代码修改如下:(3)启动MySQL数据库服务器。(4)构建并运行程序。程序运行完成后,打开phpMyAdmin工具查看qt_examp7_8db数据库中的student数据表是否创建成功。3、插入记录插入记录有2种方法,一种是使用QSqlQuery执行SQL语句:insertintotable_name(fields_list)values(expression_list)直接插入数据;另一种是执行:insertintotable_name(fields_list)values(?,?,?,…)或insertintotable_name(fields_list)values(:fields_list)SQL语句,通过占位符绑定来插入数据。Qt支持两种占位符绑定,即位置绑定和名称绑定。【例7.10】编写一个非GUI的Qt应用程序,示例数据表中数据的插入操作。(1)复制例7.9中的examp7_9项目,将其名称修改为examp7_10。(2)打开项目examp7_10的main.cpp文件,将其中的部分代码修改如下:(3)启动MySQL数据库服务器。(4)构建并运行程序。程序运行完成后,打开phpMyAdmin工具查看qt_examp7_8db数据库中的student数据表中的数据是否插入成功。4、修改记录要修改数据表中的记录,只需要使用QSqlQuery执行下面的SQL语句即可。updatetable_namesetfield_1=expression_1[,field_2=expression_2…][fromtable1_name[,table2_name]][where…]这里也可以使用占位符绑定。【例7.11】编写一个非GUI的Qt应用程序,示例数据表中数据的更改操作。(1)复制例7.10中的examp7_10项目,将其名称修改为examp7_11。(2)打开项目examp7_11的main.cpp文件,将其中的部分代码修改如下:(3)启动MySQL数据库服务器。(4)构建并运行程序。程序运行结束后,可以看到student数据表中序号为1的学生姓名被修改为“王五”5、删除记录删除记录使用QSqlQuery执行“DELETE”SQL语句来实现。DELETE语句的语法格式为:deletefromtable_name[where…]例如,用下面的语句删除student表中姓名为“王一”的记录:deletefromstudentwherename=“王一”6、查询记录查询记录使用QSqlQuery执行“SELECT”SQL语句来实现。SELECT语句的完整语法格式较为复杂,其主要的子句如下:selectfields_listfromtable_name[where…][groupbygroup_by_expression][orderbyorder_expression[ASC|DESC]]其中,select和from子句是不可或缺的。【例7.12】编写一个非GUI的Qt应用程序,示例数据表中数据的查询操作。(1)复制例7.11中的examp7_11项目,将其名称修改为examp7_12。(2)打开项目examp7_12的main.cpp文件,将其中的部分代码修改如下:(3)启动MySQL数据库服务器。(4)构建并运行程序。课后作业思政本章结束Qt6.2/C++程序设计与桌面应用开发21世纪高等学校计算机类课程创新规划教材–微课视频版教材目录第1章初识Qt框架第2章Qt开发基础第3章界面设计组件第4章主框架窗口第5章对话框设计第6章事件系统第7章文件与数据库第8章模型/视图结构第9章图形绘制第10章多媒体编程第11章网络编程第12章进程与线程教材目录第8章模型/视图结构8.1概述8.2数据模型8.3代理组件8.4视图组件8.1概述模型/视图结构是Qt中用界面组件显示与编辑数据的一种结构,它实现了数据和界面的分离,类似于M-V-C(Model-View-Controller)程序设计模式。8.1.1基本结构Qt的模型/视图结构由三部分组成,即模型(Model)、视图(View)和代理(Delegate)。如图8.1所示。8.1.1基本结构Data(数据)就是指实际的数据源,如计算机系统的磁盘文件结构、数据库的数据表或计算机系统内存中的字符串列表(QStringList)等;Model(模型)负责数据的提取与更新,并将数据提供给视图显示或编辑;View(视图)是应用程序的界面组件,它从模型获得数据项的模型索引(ModelIndex),然后通过模型索引获取到实际的数据;Delegate(代理)的功能是让用户定制数据的界面显示和编辑方式,当视图中的数据被编辑时,代理通过模型索引与数据模型通信,并为数据的编辑提供一个合适的编辑器。8.1.2数据表示在Qt的模型/视图结构中,模型组件是核心,它为视图组件和代理组件提供存取数据的标准接口。不管数据源中的数据结构如何,Qt数据模型中的数据均以表格的层次结构来组织,视图组件通过这种逻辑结构来存取模型中的数据。在Qt中,常见的数据模型表现形式有3种,即列表模型(ListModel)、表格模型(TableModel)和树(TreeModel)模型。它们的数据表示方式如图8.2所示。从图中可以看出,虽然数据模型的表现形式不一样,但数据模型中存储数据的基本单元都是项(item),每个项有一个行号、一个列号,还有一个父项(parentitem)。在列表和表格模式下,所有的项都有一个相同的顶层项(rootitem);在树状结构中,尽管行号、列号、父项有点复杂,但是由这3个参数完全可以确定一个项的位置,从而存取项的数据。1、模型索引为了确保数据的表示与数据的获取相分离,Qt引入了模型索引(modelindex)的概念。通过数据模型存取的每一个数据都使用一个模型索引来表示,视图和代理都通过这个模型索引来获取实际的数据。通常情况下,数据模型中的模型索引就是一个Qt的QModelIndex对象,它是对一块数据的临时引用,可以用来检索或修改模型中的数据。注意,QModelIndex模型索引提供的存取数据的指针是临时的,因为数据模型随时都可能对内部数据的组织形式进行更改。如果需要使用持久性的模型索引,则要使用QPersistentModelIndex对象。例如,下面的代码:QModelIndexmodelIndex=model->index(row,column,parent);获取model数据模型中行号为row、列号为column位置的数据项的模型索引。其中,参数parent表示该数据项的父项的模型索引,它也是一个QModelIndex对象。2、行号和列号在Qt数据模型中,数据一般都是以表格的形式来组织的,所以,可以通过行(row)号和列(column)号来对需要访问的数据项进行定位。需要注意的是,这并不意味着数据源中的数据是以二维数组的方式存储的,使用行号和列号只是一种约定,以确保模型/视图结构中各组件间可以相互通信。注意,数据模型中数据项的行号和列号都是从0开始的。3、父项在Qt的数据模型中,列表模型或表格模型的所有数据项都以根项(Rootitem)为父项(parentitem),所以,它们都是顶层数据项(Toplevelitem)。顶层数据项的父项模型索引统一用QModelIndex()来表示。例如,对于图8.3所示的表格模型中的3个数据项A、B和C,可以使用如下的代码来获取其模型索引。对于树模型来说,情况要复杂一些,因为并不是所有的数据项都处于顶层。树模型中的每一个数据项都可能拥有自己的父项,当然它也可能是其他数据项的父项。所以,在获取树模型数据项的模型索引时,必须明确指定其行号、列号和父项。例如,对于图8.4所示的树模型中的3个数据项A、B和C,可以使用如下的代码来获取其模型索引。4、项角色Qt数据模型中的数据项可以作为不同的角色(itemrole)在其他组件中使用,也可以为不同的情况提供不同类型的数据。例如,Qt::DisplayRole用于访问可以作为文本显示在视图中的字符串。通常情况下,数据模型中的数据项都包含了一些不同角色的数据,这些标准的角色由枚举变量Qt::ItemDataRole来定义,常用的角色如表8.1所示。通过为每个角色提供适当的项目数据,模型可以为视图和代理提供提示,告诉它们数据应该怎样展示给用户。角色指出了从模型中引用哪种类型的数据,视图可以使用不同的方式来显示不同的角色,如图8.5所示。8.1.3相关Qt类模型/视图结构功能是通过众多的Qt类共同实现的,这些类按功能分为3组,分别为模型类、视图类和代理类。1、模型类模型类也被称为数据模型类或数据模型组件。在Qt中,所有基于项数据(itemdata)的数据模型都是基于QAbstractItemModel类的,这个类定义了视图和代理存取数据的接口。2、视图类在Qt的模型/视图结构中,与视图相关的几个主要类及其描述,如表8.3所示。3、代理类在Qt的模型/视图结构中,与委托代理相关的几个主要类及其描述如表8.4所示。8.2数据模型数据模型是Qt模型/视图结构的核心,它实现了数据与视图的分离。下面介绍几种常用的数据模型的使用方法。8.2.1QAbstractListModel模型QAbstractListModel是所有一维列表数据模型的抽象基类,它继承自QAbstractItemModel类,又被QStringListModel、QVirtualKeyboardSelectionListModel和QWebEngineHistoryModel类直接继承。QAbstractListModel类是抽象类,不能直接实例化,程序中使用其子类来创建数据模型。下面是QStringListModel数据模型类的继承关系【例8.1】编写一个Qt应用程序演示QStringListModel数据模型的使用方法。(1)启动QtCreator集成开发环境,创建一个名为examp8_1的Qt应用程序。该应用程序主窗口基于QMainWindow类。(2)双击项目界面文件mainwindow.ui,打开QtDesigner界面设计工具。在QtDesigner中设置应用程序主窗口界面,设计工具栏上的功能按钮及相应的槽函数,添加列表项单击信号的槽函数。界面对象名称及属性请参见教材源码。(3)在项目主窗口类MainWindow中添加QStringListModel数据模型指针model,以及初始化数据模型和列表视图的私有成员函数initModel()和initView()。代码如下:(4)打开mainwindow.cpp文件,添加成员函数initModel()和initView()的实现代码。(5)在MainWindow类的构造函数中调用initModel()和initView()函数,完成数据模型和视图的初始化工作。(6)在槽函数中添加代码,实现工具按钮的相应功能。代码如下:(7)实现状态栏信息提示功能。当用户单击列表项中的数据项时,在应用程序状态栏中显示该数据项的行号和列号信息。代码如下:(8)构建并运行程序。8.2.2QFileSystemModel模型QFileSystemModel数据模型用于访问本机文件系统数据,将该数据模型与视图组件QTreeView结合,可以实现本机文件系统资源的目录树显示。QFileSystemModel类继承于QAbstractItemModel,它没有被其他类继承。该类提供了丰富的成员函数,可以使用这些成员函数来创建目录、删除目录、重命名目录,获取文件名称、目录名称、文件大小和详细信息等。【例8.2】使用QFileSystemModel数据模型,实现一个简单的文件资源浏览器。(1)启动QtCreator集成开发环境,创建一个名称为examp8_2的Qt应用程序。选择主窗口基类QWidget,不生成界面文件。(2)创建模型及视图对象。打开项目文件widget.h,在其中添加如下代码,为主窗口类Widget创建私有访问权限的数据模型及视图组件对象。(3)初始化数据模型及视图对象。打开项目文件widget.cpp,在主窗口类Widget的构造函数中添加代码,对主窗口、数据模型及视图进行初始化。代码如下:(4)构建并运行程序。8.2.3QStandardItemModel模型QStandardItemModel是以项数据为基础的标准数据模型类,它继承自QAbstractItemModel,没有直接子类。其部分成员函数及功能如表8.7所示。【例8.3】编写一个Qt应用程序,演示QStandardItemModel数据模型的使用方法。(1)启动QtCreator集成开发环境,创建一个名为examp8_3的Qt应用程序。该应用程序主窗口基于QWidget类。(2)打开Widget.h头文件,在Widget类中添加数据模型对象指针model及成员函数createModel()和initView()。代码如下:(3)打开Widget.cpp文件,编写createModel()和initView()函数的实现代码,并在Widget类的构造函数中调用它们。代码如下:(4)构建并运行程序。8.2.4QAbstractTableMode模型QAbstractTableMode是所有表格数据模型的抽象基类,它继承自QAbstractItemModel其直接子类为QSqlQueryModel类,间接子类还有QSqlTableModel类和QSqlRelationalTableModel类。这些类之间的继承关系如图8.10所示。QAbstractTableMode类定义了一些表模型的公共接口,它不能被直接实例化,实际编程时需要使用它的3个子类对象。1、QSqlQueryModelQSqlQueryModel是一个基于SQL查询的只读数据模型。它封装了执行SELECT语句从数据库查询数据的功能,只能作为只读数据源使用,不能对数据库中的数据进行编辑。【例8.4】编写一个Qt应用程序,演示QSqlQueryModel数据模型的使用方法。(1)创建一个名为qt_examp8_4db的MySQL数据库,并在库中添加一张名为students的数据表。Students数据表的字段及测试数据如图8.12所示。(2)启动QtCreator集成开发环境,创建一个名为examp8_4的Qt应用程序。该应用程序主窗口基于QMainWindow类。(3)双击mainwindow.ui界面文件,打开QtDesigner设计工具。删除默认的菜单栏;在主窗口中心区域添加一个名tableView的QTableView视图组件;创建一个名为“打开”的Action,并将其添加到工具栏上。(4)打开mainwindow.h文件,为类MainWindow添加2个私有成员变量db和model,分别表示数据库和数据模型。如下所示。(5)打开mainwindow.cpp文件,在“打开”Action的槽函数中编写代码。如下所示。(6)构建并运行程序。2、QSqlTableModelQSqlTableModel

继承自QSqlQueryModel类,它是一个直接根据数据表名称来对数据表进行读/写的数据模型。使用该模型不需要熟悉SQL命令语法,只需要调用相应的函数即可。例如,下面的代码:【例8.5】编写一个Qt应用程序,演示QSqlTableModel数据模型的使用方法。(1)复制例8.4中的examp8_4项目,将项目名称修改为examp8_5。(2)启动QtCreator集成开发环境,打开项目examp8_5,将主窗口标题修改为“例8.5”。(3)打开mainwindow.cpp文件,修改槽函数on_action_open_triggered()中的代码如下所示。将原代码中的:

model=newQSqlQueryModel(this);model->setQuery("select*fromstudents");修改为:

model=newQSqlTableModel(this);model->setTable("students");model->select();(4)构建并运行程序。3、QSqlRelationalTableModelQSqlRelationalTableModel继承自QSqlTableModel类,并且对其进行了扩展,提供了对数据表中外键的支持。也就是说,QSqlRelationalTableModel是可以处理关系数据表的数据模型。QSqlRelationalTableModel类的主要函数与QSqlTableModel类相同。不同的是,它新增了一个名为setRelation()成员函数,用于设置外键的关联数据表和关联字段。【例8.6】编写一个Qt应用程序,演示QSqlRelationalTableModel数据模型的使用方法。(1)创建一个名为qt_examp8_6db的MySQL数据库,并在库中创建students、departments和majors三张数据表。数据表字段名称及测试数据如图8.14~8.16所示。(2)复制例8.5中的examp8_5项目,将项目名称修改为examp8_6。(3)启动QtCreator集成开发环境,打开项目examp8_5,将主窗口标题修改为“例8.6”。(4)打开mainwindow.cpp文件,修改槽函数MainWindow::on_action_open_triggered()中的代码,如下所示。(5)构建并运行程序。8.3代理组件在Qt的数据模型/视图结构中,代理组件主要用于数据的编辑,分为缺省代理和自定义代理两大类。8.3.1缺省代理一般情况下,模型/视图结构中的视图组件都会提供一个缺省的代理组件,来实现视图与数据模型之间数据的同步更新。8.3.1缺省代理【例8.7】一个简单的缺省代理应用实例。(1)复制例8.5中的项目examp8_5,并将名称修改为examp8_7。(2)启动QtCreator集成开发环境,打开项目examp8_7。为项目中添加2个新的工具栏按钮,其中“保存”按钮用于手动保存数据的更改;“撤销”按钮用于取消数据在保存之前的更改操作。为视图组件tableView添加一个双击信号的槽函数on_tableView_doubleClicked()。(3)打开mainwindow.cpp文件,在槽函数on_action_open_triggered()中添加如下代码,设置数据模型的数据保存方式。model->setEditStrategy(QSqlTableModel::OnManualSubmit);QSqlTableModel::OnManualSubmit为手动数据保存方式。(4)在槽函数on_action_save_triggered()、on_action_undo_triggered()和on_tableView_doubleClicked()中编写代码,实现数据保存及撤销功能。如下所示。(5)构建并运行程序。8.3.2自定义代理在一般的情况下,Qt模型/视图结构中的缺省代理编辑器可以满足应用程序开发的需要,但有时候仍然显得不够灵活。例如,双击图8.17中的“性别”数据单元格,显示的是QLineEdit类型的缺省代理编辑组件,对于枚举类型的数据使用文本框输入就不是很方便。此时,需要自己定义一个合适的代理编辑组件,比如QComboBox组合框组件,如图8.18所示。【例8.8】一个简单的自定义代理实例。本实例程序在例8.7项目基础上实现,运行结果如图8.18所示。(1)复制例8.7中的项目examp8_7,将项目名称修改为examp8_8。(2)启动QtCreator集成开发环境,打开项目examp8_8。在项目中添加一个名为ComboDelegate的C++类。(3)在类ComboDelegate中添加4个公有成员函数,分别为createEditor()、setEditorData()、setModelData()和updateEditorGeometry()。(4)在类ComboDelegate的实现文件中编写代码,实现自定义的4个成员函数的功能。(5)打开mainwindow.h文件,在MainWindow类添加一个私有的ComboDelegate对象。如下所示。private:ComboDelegatecomboDelegate;接着,打开mainwindow.cpp文件,在槽函数on_action_open_triggered()中添加代码,为视图组件添加自定义的代理组件。如下所示。ui->tableView->setItemDelegateForColumn(3,&comboDelegate);(6)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论