Part 06 项目视图(Widget)(Qt)
——2012.02.16
0. 本次学习Qt时主要方法:分析代码,理清原代码思路,重写代码,将数代码整合至一个主窗口中实现。
1. 编写学习笔记主要形式:展示程序功能,分析程序编写思路,展示(经修改整合的)程序代码。
2. 主要参考学习资料: Qt Assistant与Qt学习之路(39~41)(豆子空间)。
3. 本Part内容:了解项目视图的有哪些基本类型,附:Windows显示中文字符方法。QGripLayout使用。
附:本次主要要使用到的类的类继承关系图
012 Program – QItemView(Widget)
01. 展示程序功能
可以看出,该主窗口的内容可以分为五大块,包含了五个QItemWidget,三种类型的QItemWidget:
第一种类型是ListWidget在左上角一个分块和左下角的一个分块的这两个视图;
第二种类型是中间的Tree Widget字样的两个视图,这两个视图稍有不同,“Tree Widget 1”的窗口内,只有一个题目称为“1”,在展开的树状图上面,只有它们的名称,而“Tree Widget 2”的窗口,在抬头有两个标题“Name”和“Number”,位于树中第一列的是树的名称,第二列,是数值,它们能分栏对齐显示;
第三种类型,“Table Widget”这种类型是一个表格,图中是一个3*5的表格,在第一列中有数值,第二列中有一个单元格有数据。
上图,鼠标位置,是在“List Widget 1”内,该widget内的数据呈列表的方式排列,然后,当鼠标点击某一个数据时,左边的标签的字符也会随之改变。
上图,鼠标位置,是在“List Widget 2”内,该widget内的数据以图标为突出显示的列表方式排列,然后,当鼠标点击某一个数据时,左边的标签的字符也会随之改变。
如上图,在Table Widget中,上面表格中的单元格的数据可改变。
02. 分析程序编写思路
本程序使用了一个类以完成这些功能,该类中,以QGridLayout类用以布局。
首先留意主窗口,主窗口中并无工具栏,菜单栏,状态栏,因此,可直接使用一个central Widget完成功能。
然后,在该central Widget中,又可分为五个块,因此,可以将这五个块的主要对象作为私有成员,然后,再对这几个私有成员进行初始化,每个私有成员,可以使用一个函数来初始化,初始化的函数放于该类的构造函数中调用。
最后,这里,在编程时,发现了一个问题,Qt如果不包含其它类的情况下,直接使用QString输出中文字符,将会显示乱码,经请教,有一解决方法,在main函数中 #include <QTextCodec>,然后再添加语句,QTextCodec::setCodecForTr(QTextCodec::codecForLocale());这样,就能在windows平台下正常地显示输入中文了。
至于类中各widget的实现方法,可以看下面的内容,程序代码,一般情况下,注释都能看得懂了。
03. 程序代码
// main.cpp
#include "itemview.h"
#include <QtGui/QApplication>
#include <QTextCodec> // 让QString支持中文
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTextCodec::setCodecForTr(QTextCodec::codecForLocale()); // 让QString支持中文,Windows平台
itemView w;
w.setWindowIcon(QIcon(":/itemView/Resources/main.png"));
w.show();
return a.exec();
}
// itemview.h -- 项目视图类
#ifndef ITEMVIEW_H
#define ITEMVIEW_H
#include <QtGui/QMainWindow>
class QListWidget;
class QTreeWidget;
class QTableWidget;
class QHBoxLayout;
class itemView : public QMainWindow
{
Q_OBJECT
public:
itemView(QWidget *parent = 0, Qt::WFlags flags = 0);
~itemView();
private:
// 对各项目视图通过函数定义进行初始化
void listWidget1Construction();
void listWidget2Construction();
void treeWidget1Construction();
void treeWidget2Construction();
void tableWidgetConstruction();
// 对各项目视图声明。
QListWidget * listWidget1;
QListWidget * listWidget2;
QHBoxLayout * listWidget1Layout;
QHBoxLayout * listWidget2Layout;
QTreeWidget * treeWidget1;
QTreeWidget * treeWidget2;
QTableWidget * tableWidget;
};
#endif // ITEMVIEW_H
// itemview.cpp
#include "itemview.h"
#include <qlayout.h>
#include <qlistwidget.h>
#include <qtreewidget.h>
#include <qtablewidget.h>
#include <qlabel.h>
#include <qstringlist.h>
#include <qstring.h>
/**
* itemView的构造函数
* 操作:itemView::itemView(QWidget, Qt::WFlags)
* 后置条件:将全部的私有成员初始化完毕,完成主窗口的布局。
*/
itemView::itemView(QWidget *parent, Qt::WFlags flags): QMainWindow(parent, flags)
{
// 初始化各项目图
listWidget1Construction();
listWidget2Construction();
treeWidget1Construction();
treeWidget2Construction();
tableWidgetConstruction();
// 添加QLabel标题
QLabel * listWidget1Label = new QLabel(tr("List Widget 1"));
listWidget1Label -> setTextFormat(Qt::AutoText);
QLabel * listWidget2Label = new QLabel(tr("List Widget 2"));
QLabel * treeWidget1Label = new QLabel(tr("Tree Widget 1"));
QLabel * treeWidget2Label = new QLabel(tr("Tree Widget 2"));
QLabel * tableWidgetLabel = new QLabel(tr("Table Widget"));
// 布局
QGridLayout * allLayout = new QGridLayout;
allLayout -> addWidget(listWidget1Label, 0, 0);
allLayout -> addLayout(listWidget1Layout, 1, 0);
allLayout -> addWidget(listWidget2Label, 3, 0);
allLayout -> addLayout(listWidget2Layout, 4, 0);
allLayout -> addWidget(treeWidget1Label, 0, 2);
allLayout -> addWidget(treeWidget1, 1, 2);
allLayout -> addWidget(treeWidget2Label, 3, 2);
allLayout -> addWidget(treeWidget2, 4, 2);
allLayout -> addWidget(tableWidgetLabel, 0, 4);
allLayout -> addWidget(tableWidget, 1, 4);
allLayout -> setColumnMinimumWidth(4, 330);
// 安装主窗口
QWidget * centralWidget = new QWidget(this);
centralWidget -> setLayout(allLayout);
this -> setCentralWidget(centralWidget);
}
/**
* 操作: void itemView::listWidget1Constraction();
* 前置条件:在类中有QListWidget * listWidget1对象,包含头文件QListWidget;
* 后置条件:将私有成员中的listWidget1的各属性设置好。
* 各部件按列表的形式排列,并且能使QLabel界面内的部件响应鼠标操作.
*/
void itemView::listWidget1Construction()
{
listWidget1 = new QListWidget;
// 设标签
QLabel * listWidgetQLabel1 = new QLabel(tr("NULL"));
listWidgetQLabel1 -> setFixedWidth(30);
// 加项目入列表
listWidget1 -> addItem(new QListWidgetItem(QIcon(":/itemView/Resources/line.png"), tr("Line")));
listWidget1 -> addItem(new QListWidgetItem(QIcon(":/itemView/Resources/oval.png"), tr("oval")));
listWidget1 -> addItem(new QListWidgetItem(QIcon(":/itemView/Resources/rectangle.png"), tr("rectangle")));
listWidget1 -> addItem(new QListWidgetItem(QIcon(":/itemView/Resources/triangle.png"), tr("triangle")));
// 设置模式,布局
listWidget1 -> setViewMode(QListView::ListMode);
listWidget1Layout = new QHBoxLayout;
listWidget1Layout -> addWidget(listWidgetQLabel1);
listWidget1Layout -> addWidget(listWidget1);
// 连接
connect(listWidget1, SIGNAL(currentTextChanged(QString)), listWidgetQLabel1, SLOT(setText(QString)));
return;
}
/**
* 操作: void itemView::listWidget2Constraction();
* 前置条件:在类中有QListWidget * listWidget2对象,包含头文件QListWidget;
* 后置条件:将私有成员中的listWidget1的各属性设置好。
* 各部件按图标列表的形式排列,并且能使QLabel界面内的部件响应鼠标操作.
*/
void itemView::listWidget2Construction()
{
listWidget2 = new QListWidget;
// 设标签
QLabel * listWidgetQLabel2 = new QLabel(tr("NULL"));
listWidgetQLabel2 -> setFixedWidth(30);
// 加项目入列表
listWidget2 -> addItem(new QListWidgetItem(QIcon(":/itemView/Resources/line.png"), tr("Line")));
listWidget2 -> addItem(new QListWidgetItem(QIcon(":/itemView/Resources/oval.png"), tr("oval")));
listWidget2 -> addItem(new QListWidgetItem(QIcon(":/itemView/Resources/rectangle.png"), tr("rectangle")));
listWidget2 -> addItem(new QListWidgetItem(QIcon(":/itemView/Resources/triangle.png"), tr("triangle")));
// 设置模式,布局
listWidget2 -> setViewMode(QListView::IconMode);
listWidget2Layout = new QHBoxLayout;
listWidget2Layout -> addWidget(listWidgetQLabel2);
listWidget2Layout -> addWidget(listWidget2);
// 连接
connect(listWidget2, SIGNAL(currentTextChanged(QString)), listWidgetQLabel2, SLOT(setText(QString)));
return;
}
/**
* 操作: void itemView::treeWidget1Constraction();
* 前置条件:在类中有QTreeWidget * treeWidget1对象,包含头文件QTreeWidget;
* 后置条件:将私有成员中的treeWidget1的各属性设置好。简单的树形式的窗口。
*/
void itemView::treeWidget1Construction()
{
// 初始化对象,设定栏数
treeWidget1 = new QTreeWidget;
treeWidget1 -> setColumnCount(1);
// 开始定义子对象
QTreeWidgetItem * root = new QTreeWidgetItem(treeWidget1, QStringList(QString("Root")));
QTreeWidgetItem * leaf1 = new QTreeWidgetItem(root, QStringList(QString("Leaf 1")));
QTreeWidgetItem * leaf2 = new QTreeWidgetItem(root, QStringList(QString("Leaf 2")));
leaf2 -> setCheckState(0, Qt::Checked); // 将其变为可选择
// 子对象与父对象连接
root -> addChild(leaf1);
root -> addChild(leaf2);
// 将父对象加入QListItem中
QList<QTreeWidgetItem *> rootList1;
rootList1 << root;
treeWidget1 -> insertTopLevelItems(0, rootList1);
return;
}
/**
* 操作: void itemView::treeWidget2Constraction();
* 前置条件:在类中有QTreeWidget * treeWidget2对象,包含头文件QTreeWidget;
* 后置条件:将私有成员中的treeWidget2的各属性设置好。带两列及标题的树形式的窗口。
*/
void itemView::treeWidget2Construction()
{
// 初始化对象,设定栏数
treeWidget2 = new QTreeWidget;
treeWidget2 -> setColumnCount(2);
// 定义树型表的标签
QStringList headers;
headers << "Name" << "Number";
treeWidget2 -> setHeaderLabels(headers);
// 定义树型表的子对象
QStringList rootTextList;
rootTextList << "Root" << "0";
QTreeWidgetItem * root = new QTreeWidgetItem(treeWidget2, rootTextList);
QStringList leaf1TextList;
leaf1TextList << "Leaf 1" << "1";
QTreeWidgetItem * leaf1 = new QTreeWidgetItem(root, leaf1TextList);
QStringList leaf2TextList;
leaf2TextList << "Leaf 2" << "2";
QTreeWidgetItem * leaf2 = new QTreeWidgetItem(root, leaf2TextList);
leaf2 -> setCheckState(0, Qt::Checked);
// 子对象与父对象连接
root -> addChild(leaf1);
root -> addChild(leaf2);
// 将父对象加入QListItem中
QList<QTreeWidgetItem *> rootList2;
rootList2 << root;
treeWidget2 -> insertTopLevelItems(0, rootList2);
return;
}
/**
* 操作: void itemView::tableWidgetConstraction();
* 前置条件:在类中有QTableWidget * tableWidget对象,包含头文件QTableWidget;
* 后置条件:将私有成员中的tableWidget的各属性设置好。带五行三列的表格窗口。
*/
void itemView::tableWidgetConstruction()
{
// 初始化tableWidget对象,设定行列数及行列的表头
tableWidget = new QTableWidget;
tableWidget -> setColumnCount(3);
tableWidget -> setRowCount(5);
QStringList headers;
headers << "Line Number" << "ID" << "Name" << "Age" << "Sex";
tableWidget -> setHorizontalHeaderLabels(headers);
// 设置表单中的内容(以0,0为左上方第一格)
tableWidget -> setItem(0, 0, new QTableWidgetItem (QString("1"))); // 为每一行添加一个数据
tableWidget -> setItem(1, 0, new QTableWidgetItem (QString("2")));
tableWidget -> setItem(2, 0, new QTableWidgetItem (QString("3")));
tableWidget -> setItem(3, 0, new QTableWidgetItem (QString("4")));
tableWidget -> setItem(4, 0, new QTableWidgetItem (QString("5")));
tableWidget -> setItem(0, 1, new QTableWidgetItem (QString(tr("第一行第二列"))));
return;
}
itemView::~itemView()
{
}
04. 未解问题
在主窗口中,现在每个widget的标题的对齐方式是左对齐,如何能将它们调至居中的对齐方式。