qt mvc3

前面两节讲的model是一维的,这次开始二维的也就是我们常说的Table,相对与list,我们多了一个列的概念。

下面讲解一个例子。我先说明一下我们这个例子,在程序目录下,我们有一个文本文件,其中存放的学生信息。

数据存放的格式

学号
姓名 性别

xxx xxx
x

每个学生的信息占一行,现在我们需要将这个文件中的所有学生信息加载显示。

在例子中主要涉及这几个类,Student,FileReader和DataTableModel类。

Student是学生实体类,FileRead从文件加载数据,后面的一个就是我们的model了。

下面代码贴出来

Student

#ifndef
STUDENT_HPP
#define STUDENT_HPP
#include <QString>
#include
<QTextStream>

class Student
{
friend
QTextStream& operator >>(QTextStream &in,Student &t) {

in >> t.m_no >> t.m_name >> t.m_sex;
return
in;
}

public:
Student(){}
Student(const
QString &no, const QString &name,const QString &sex);
const
QString& getNo() const;
const QString& getName() const;

const QString& getSex() const;

static int members() {

return 3;
}

QString operator [](int i) const{


switch (i) {
case 0:
return m_no;

case 1:
return m_name;
case 2:

return m_sex;
default:
break;

}
return QString();
}

static QString
describe(int i) {
switch (i) {
case 0:

return "No.";
case 1:
return "Name";

case 2:
return "Sex";
default:

break;
}
return QString();
}


private:
QString m_no;
QString m_name;

QString m_sex;

};

#endif // STUDENT_HPP

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

#include "student.hpp"

Student::Student(const QString &no,
const QString &name, const QString &sex):
m_no(no),

m_name(name),
m_sex(sex)
{
}

inline
const
QString& Student::getNo() const
{
return m_no;
}


inline
const QString& Student::getName() const
{

return m_name;
}

inline
const QString& Student::getSex()
const
{
return m_sex;
}

Student类有三个数据成员,m_no学号,m_name姓名,m_sex性别。两个静态成员函数对类属性的一些描述,这个是侵入性的,后面优化可以是非侵入式的。

重载的[]是为了使用方便,>>是为了支持流。

FileReader是一个模板类

[cpp]
view
plaincopyprint?
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

#ifndef
FILEREADER_HPP
#define FILEREADER_HPP
#include <QFile>

#include <QTextStream>

#include "student.hpp"


//you also can use QDataStream

template <typename T>

class FileReader
{
public:
FileReader(const QString
&name);
~FileReader();
bool open();
bool
hasNext();
T getNext();
private:
QString m_fileName;

QFile m_file;
QTextStream m_stream;

};


template <typename T>
inline

FileReader<T>::FileReader(const QString &name):m_fileName(name)

{

}

template <typename T>

FileReader<T>::~FileReader()
{
if (m_file.isOpen()) {

m_file.close();
}
}

template <typename
T>
bool FileReader<T>::open()
{

m_file.setFileName(m_fileName);
if (m_file.open(QIODevice::ReadWrite))
{
m_stream.setDevice(&m_file);
return true;

}
return false;
}
template <typename T>
bool
FileReader<T>::hasNext()
{
if (m_file.isOpen()) {

return !m_stream.atEnd();
}
return false;
}


template <typename T>
T FileReader<T>::getNext()
{

T t;
m_stream >> t;
return t;
}


#endif // FILEREADER_HPP

构造参数是加载数据的文件名,提供了open操作,hasNext是判断是否结束,getNext得到一个加载的对象。

下面是我们的models,其中我使用了我的蹩脚的英文写了注释

[cpp]
view plaincopyprint?

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

#ifndef DATATABLEMODEL_HPP
#define DATATABLEMODEL_HPP

#include
<QAbstractTableModel>
#include <vector>

#include
"student.hpp"
#include "filereader.hpp"

//Here,I want to use
‘template class‘,but is not supported by the macor ‘Q_OBJECT‘,
//so I use
typedef,of cause you also use macor
//If you want to use it,the type of T
use should implement the two static function
//and overload operator[] and
>>--int members(),it return T numbers of members,
//QString
describe(int ),the describe about T.operator[](int i),return the i-st member
data.
//the >> you know
typedef Student T;

class
DataTableModel : public QAbstractTableModel
{
Q_OBJECT

public:
explicit DataTableModel(const QString &fileName,QObject
*parent = 0);

int rowCount(const QModelIndex &parent) const;

int columnCount(const QModelIndex &parent) const;

Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant
data(const QModelIndex &index, int role) const;
QVariant
headerData(int section, Qt::Orientation orientation, int role) const;

signals:
void sig_error(const QString &info);
public
slots:
private:
QString m_fileName;
//use vector,loading
data form file may low speed,but seaching is fast!
std::vector<T>
m_data;

void load();
};

#endif //
DATATABLEMODEL_HPP

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

#include "datatablemodel.hpp"


DataTableModel::DataTableModel(const QString &fileName, QObject
*parent):
QAbstractTableModel(parent),
m_fileName(fileName)

{
load();
}

int DataTableModel::rowCount(const
QModelIndex &/*parent*/) const
{
return m_data.size();
}


int DataTableModel::columnCount(const QModelIndex &/*parent*/) const

{
return T::members();
}

Qt::ItemFlags
DataTableModel::flags(const QModelIndex &/*index*/) const
{

return Qt::ItemIsEnabled;
}

QVariant
DataTableModel::data(const QModelIndex &index, int role) const
{

if (index.isValid() && role == Qt::DisplayRole) {
return
m_data[index.row()][index.column()];
}
return QVariant();

}

QVariant DataTableModel::headerData(int section,
Qt::Orientation orientation, int role) const
{
if (role !=
Qt::DisplayRole) {
return QVariant();
}
if
(orientation == Qt::Vertical) {
return QString("row
%1").arg(section);
} else {
return T::describe(section);

}
return QVariant();
}
/**
* @brief
DataTableModel::load load data from file
*/
void
DataTableModel::load()
{
//create a file reader that can read
object about type of T from file
//which name is m_fileName,the type of
T should overload the operator >> on QTextStream.
//A bug about
FileReader,the last read is empty because the file is end with empty line.

//But I think it is not a problem.
FileReader<T>
fr(m_fileName);
if (fr.open()) {
while (fr.hasNext()) {

m_data.push_back(fr.getNext());
}
} else {

emit sig_error("load data failure!");
}
}

本来是想也做成模板的,可是Qt元对象系统和模板机制是存在冲突的,以后讲为什么冲突。这里我使用了typedef来提前做了编译器应该做的事避免了冲突

data,rowCounts,flag,headerData这些都是需要重新实现的,在二维中columnCount就需要重新实现了。

只是为了显示所以flag很简单。

大家也看见了我在Student中实现的members,describe的用处,和重载[]所带来的便捷。

我们的列数就是需要对外实现的成员数,describe就是得到成员的描述。其实我感觉已经有点框架的味道了...算了不说大话了

其中的一个bug我已经用英文说了。

无图无真相

时间: 2024-10-27 07:35:22

qt mvc3的相关文章

Qt编译好的OCI驱动下载

在上文,我累赘了一大堆,给大家写了一篇Qt如何编译OCI驱动,在这里自然就不再累赘了,直接附上编译好的文件供大家下载: <Qt5.3.1+OCI驱动下载地址> 有经济来源的请传送:http://download.csdn.net/detail/u012433546/9922424 无经济来源的请传送:链接:http://pan.baidu.com/s/1boKG9lH 密码:7yj5 <Qt5.3.2+OCI驱动下载地址> 有经济来源的请传送:http://download.csd

Qt线程的简单使用(一)

Qt中线程的一种创建方式,就是使用QObject::moveToThread()函数.如下,直接上源代码,可以把费时的任务放到doWork()方法里进行,不阻塞主线程. 1 #ifndef WORKER_H 2 #define WORKER_H 3 4 #include <QObject> 5 6 class Worker : public QObject 7 { 8 Q_OBJECT 9 10 public: 11 Worker(); 12 ~Worker(); 13 public slot

第三十八课、Qt中的事件处理(上)

一.图形界面应用程序的消息处理模型 二.Qt的事件处理 1.Qt平台将系统产生的消息转换为Qt事件(每一个系统消息对象Qt平台的一个事件) (1).Qt事件是一个QEvent的对象 (2).Qt事件用于描述程序内部或者外部发生的动作 (3).任意的QObject对象都具备事件处理的能力 2.GUI应用程序的事件处理方式 (1).Qt事件产生后立即被分发到QWidget对象 (2).QWidget中的event(QEvent*)进行事件处理 (3).event()根据事件类型调用不同的事件处理函数

MISP版本嵌入式QT编译时出现mips-linux-gcc command not found

configure的时候都没什么问题我的configure是:./configure -prefix /opt/qt-jz -xplatform qws/linux-mips-g++ -embedded mips  configure顺利的过了,但是当make的时候,出现了mips-linux-gcc :Commond not fount! 我装的是mipsl-linux-gcc ,而且已经交叉编译过了个hello world了.. make时出现的错误是:make[1]: Entering d

Qt在Mac OS X下的编程环境搭建(配置Qt库和编译器,有图,很清楚)

尊重作者,支持原创,如需转载,请附上原地址:http://blog.csdn.net/libaineu2004/article/details/46234079 在Mac OS X下使用Qt开发,需要配置Qt库和编译器.编译器只能使用苹果公司自主研发的Clang.1.分别下载并安装XCode和Command Line Tools(必须安装),安装完毕后,Clang就有了. https://developer.apple.com/downloads/ 2.下载Qt并默认安装 http://down

让Qt在MIPS Linux上运行 good

下载 首先下载Qt everywhere,当前的版本是4.7.2,可以从nokia的网站上下载,也可以从git服务器上下载.考虑到文件有200M 以上的大小,下载速率低于25kBPS的,需要考虑从什么地方复制一份,否则需要等待较长时间才能下载下来.我是在家里下载这个文件的,所以开始编译已经是第二天了.考虑提升员工效率的话,需要预先预备好这些下载文件,或者增加接入带宽. 解压 第一步下载的文件是一个tar包,所以需要解压,通常解压需要在unix/Linux环境下进行,如果只是看代码,windows

qt.network.ssl: QSslSocket: cannot call unresolved function SSLv23_client_method

最近在做一个网络音乐播放器时,由于出现qt.network.ssl: QSslSocket: cannot call unresolved function SSLv23_client_method, 而不能播放网络歌曲. 上网搜了半天,都说要在电脑那里安装openssl,然后把C:\OpenSSL-Win64\bin下的libeay32.dll和ssleay32.dll拷贝到D:\Qt\Qt5.4.2\5.4\mingw491_32\bin, 然而并没什么卵用! 我的解决办法是: Qt的这个目

Qt中单例模式的实现(4种方法)

最简单的写法: 12345 static MyClass* MyClass::Instance(){ static MyClass inst; return &inst;} 过去很长一段时间一直都这么写,简单粗暴有效.但是直接声明静态对象会使编译出的可执行文件增大,也有可能出现其他的一些问题,所以利用了Qt自带的智能指针QScopedPointer和线程锁QMutex,改成了需要时才动态初始化的模式: 12345678910111213 static MyClass* MyClass::Inst

QT Object 错误

今天在测试多线程时定义一个类 继承QTHread 结果包含QT  Object  造成QT 构造函数失败 #ifndef THREAD_H#define THREAD_H#include <QThread>#include <iostream>#include <QObject>//class mythread : public QThreadclass mythread : public QThread{   // Q_OBJECT  (未继承object 而是使用这