异度部落格

学习是一种生活态度。

0%

这里利用 Qt4+MySQL 做一个简单的例子

不会连接 MySQL 的,参考这里:http://blog.csdn.net/killua_hzl/archive/2009/07/29/4391956.aspx

代码如下:

studentmanage.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef STUDENTMANAGE_H
#define STUDENTMANAGE_H
#include <QtGui/QWidget>
class QSqlTableModel;
class QTableView;
enum { Stu_Sno = 0,Stu_Name = 1,Stu_Age = 2,Stu_Math = 3,Stu_Chinese = 4,Stu_English = 5 };
class StudentManage : public QWidget
{
Q_OBJECT
public:
StudentManage(QWidget *parent = 0);
~StudentManage();
private:
QSqlTableModel *model;
QTableView *view;
};
#endif // STUDENTMANAGE_H

studentmanage.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <QtGui>
#include <QtSql>
#include "studentmanage.h"
StudentManage::StudentManage(QWidget *parent)
: QWidget(parent)
{
model = new QSqlTableModel(this);
model->setTable("student");
model->setSort(Stu_Sno, Qt::AscendingOrder);
model->setHeaderData(Stu_Name, Qt::Horizontal, tr("Name"));
model->setHeaderData(Stu_Age, Qt::Horizontal, tr("Age"));
model->setHeaderData(Stu_Math, Qt::Horizontal, tr("Math"));
model->setHeaderData(Stu_Chinese, Qt::Horizontal, tr("Chinese"));
model->setHeaderData(Stu_English, Qt::Horizontal, tr("English"));
model->select();
view = new QTableView;
view->setModel(model);
view->setSelectionMode(QAbstractItemView::SingleSelection);
view->setSelectionBehavior(QAbstractItemView::SelectRows);
view->resizeColumnsToContents();
view->setEditTriggers(QAbstractItemView::NoEditTriggers);
QHeaderView *headerView = view->horizontalHeader();
headerView->setStretchLastSection(true);
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(view);
setLayout(layout);
setWindowTitle(tr("Student Manage"));
}
StudentManage::~StudentManage()
{
}

main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <QtGui/QApplication>
#include <QtSql>
#include <QMessageBox>
#include "studentmanage.h"
/**
建立数据库链接
*/
bool createConnection()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");
db.setDatabaseName("DB_Stu");
db.setUserName("root");
db.setPassword("123456");
if (!db.open()) {
QMessageBox::warning(0, QObject::tr("Database Error"),
db.lastError().text());
return false;
}
return true;
}
/**
创建数据
*/
void createData()
{
QSqlQuery query;
query.exec("Drop table student"); //如果表存在删除
//建表
query.exec("Create table student ("
"Sno int not null,"
"Name varchar(40) not null,"
"Age int not null,"
"Math int not null,"
"Chinese int not null,"
"English int not null)");
//插入数据
query.exec("Insert into student (Sno,Name,Age,Math,Chinese,English) values(1,'Dear_fox',1,100,100,100)");
query.exec("Insert into student (Sno,Name,Age,Math,Chinese,English) values(2,'Killua',2,99,98,98)");
}
/**
主函数
*/
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
bool isCreate = !QFile::exists("DB_Stu");
if (!createConnection())
return 1;
if(isCreate)
createData();
StudentManage studentManage;
studentManage.resize(400,300);
studentManage.show();
return a.exec();
}

结果截图: ed4fa4671bc2ab0697d9b2d1680f92d8.png

貌似好久没写了,最近比较忙的说,这个主要练习 Model 的设计,部分代码是参考别人的,大牛们不要鄙视啊....

源码最后附上。

部分核心代码如下:

booleanmodel.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef BOOLEANMODEL_H
#define BOOLEANMODEL_H
#include <QAbstractItemModel>
class Node;
class BooleanModel : public QAbstractItemModel
{
Q_OBJECT
public:
BooleanModel(QObject *parent = 0);
~BooleanModel();
void setRootNode(Node *node);
QModelIndex index(int row, int column, const QModelIndex &parent) const;
QModelIndex parent(const QModelIndex &child) const;
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section,Qt::Orientation orientation, int role) const;
private:
Node *nodeFromIndex(const QModelIndex &index) const;
Node *rootNode;
};
#endif // BOOLEANMODEL_H

booleanmodel.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include <QtCore>
#include "booleanmodel.h"
#include "booleanparser.h"
/**
构造函数,初始化根结点为空
*/
BooleanModel::BooleanModel(QObject *parent) :QAbstractItemModel(parent)
{
rootNode = 0;
}
/**
析构函数,删除根结点
*/
BooleanModel::~BooleanModel()
{
delete rootNode;
}
/**
设置根结点,删除原来根结点,重新设置根结点
*/
void BooleanModel::setRootNode(Node *node)
{
delete rootNode;
rootNode = node;
reset(); //刷新表格数据
}
/**
返回索引,这个是virtual函数所以一定要重载
*/
QModelIndex BooleanModel::index(int row,int column,const QModelIndex &parent) const
{
if (!rootNode || row < 0 || column < 0)
return QModelIndex(); //非法情况
Node *parentNode = nodeFromIndex(parent);
Node *childNode = parentNode->children.value(row);
if (!childNode)
return QModelIndex();
return createIndex(row,column, childNode);
}
/**
返回父亲结点
*/
QModelIndex BooleanModel::parent(const QModelIndex &child) const
{
Node *node = nodeFromIndex(child);
if (!node)
return QModelIndex(); //结点无效
Node *parentNode = node->parent;
if (!parentNode)
return QModelIndex(); //父结点无效
Node *grandparentNode = parentNode->parent;
if(!grandparentNode)
return QModelIndex(); //父结点的父结点无效
int row = grandparentNode->children.indexOf(parentNode);
return createIndex(row,0,parentNode);
}
/**
返回行数,这个也是virtual函数,要重载
*/
int BooleanModel::rowCount(const QModelIndex &parent) const
{
if (parent.column() > 0)
return 0;
Node *parentNode = nodeFromIndex(parent);
if(!parentNode)
return 0;
return parentNode->children.count();
}
/**
返回列数,固定只有2,这个也是virtual函数,要重载
*/
int BooleanModel::columnCount(const QModelIndex & /*parent*/) const
{
return 2;
}
/**
返回数据,这个也是virtual函数,要重载
*/
QVariant BooleanModel::data(const QModelIndex &index, int role) const
{
if (role != Qt::DisplayRole)
return QVariant(); //不是显示角色,认为是无效数据
Node *node = nodeFromIndex(index);
if (!node)
return QVariant(); //结点无效
if(index.column() == 0) {
switch (node->type) {
case Node::Root:
return tr("Root");
case Node::OrExpression:
return tr("OR Expression");
case Node::AndExpression:
return tr("AND Expression");
case Node::NotExpression:
return tr("NOT Expression");
case Node::Atom:
return tr("Atom");
case Node::Identifier:
return tr("Identifier");
case Node::Operator:
return tr("Operator");
case Node::Punctuator:
return tr("Punctuator");
default:
return tr("Unknown"); //默认为未知
}
} else if(index.column() == 1) {
return node->str;
}
return QVariant();
}
/**
返回表头
*/
QVariant BooleanModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
if (section == 0) {
return tr("Node");
} else if (section == 1) {
return tr("Value");
}
}
return QVariant();
}
/**
从索引返回结点
*/
Node *BooleanModel::nodeFromIndex(const QModelIndex &index) const
{
if (index.isValid()) {
return static_cast<Node *>(index.internalPointer());
} else {
return rootNode;
}
}

booleanparser.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef BOOLEANPARSER_H
#define BOOLEANPARSER_H
#include "node.h"
class BooleanParser
{
public:
BooleanParser();
Node *parse(const QString &expr);
private:
Node *parseOrExpression();
Node *parseAndExpression();
Node *parseNotExpression();
Node *parseAtom();
Node *parseIdentifier();
void addChild(Node *parent, Node *child);
void addToken(Node *parent, const QString &str, Node::Type type);
bool matchToken(const QString &str) const;
QString in;
int pos;
};
#endif // BOOLEANPARSER_H

booleanparser.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include <QtCore>
#include "booleanparser.h"
#include "node.h"
BooleanParser::BooleanParser()
{
}
Node *BooleanParser::parse(const QString &expr)
{
in = expr;
in.replace(" ", "");
pos = 0;
Node *node = new Node(Node::Root);
addChild(node, parseOrExpression());
return node;
}
/**
解析或表达式
*/
Node *BooleanParser::parseOrExpression()
{
Node *childNode = parseAndExpression();
if (matchToken("||")) {
Node *node = new Node(Node::OrExpression);
addChild(node,childNode);
while (matchToken("||")) {
addToken(node,"||", Node::Operator);
addChild(node, parseAndExpression());
}
return node;
} else {
return childNode;
}
}
/**
解析与表达式
*/
Node *BooleanParser::parseAndExpression()
{
Node *childNode = parseNotExpression();
if (matchToken("&&")) {
Node *node = new Node(Node::AndExpression);
addChild(node, childNode);
while (matchToken("&&")) {
addToken(node, "&&", Node::Operator);
addChild(node, parseNotExpression());
}
return node;
} else {
return childNode;
}
}
/**
解析非表达式
*/
Node *BooleanParser::parseNotExpression()
{
if (matchToken("!")) {
Node *node = new Node(Node::NotExpression);
while (matchToken("!"))
addToken(node, "!", Node::Operator);
addChild(node, parseAtom());
return node;
} else {
return parseAtom();
}
}
/**
解析一个项
*/
Node *BooleanParser::parseAtom()
{
if (matchToken("(")) {
Node *node = new Node(Node::Atom);
addToken(node, "(", Node::Punctuator);
addChild(node, parseOrExpression());
addToken(node, ")", Node::Punctuator);
return node;
} else {
return parseIdentifier();
}
}
/**
解析标识符
*/
Node *BooleanParser::parseIdentifier()
{
int startPos = pos;
while (pos < in.length() && in[pos].isLetterOrNumber())
++pos;
if (pos > startPos) {
return new Node(Node::Identifier,
in.mid(startPos, pos - startPos));
} else {
return 0;
}
}
/**
添加子结点
*/
void BooleanParser::addChild(Node *parent, Node *child)
{
if (child) {
parent->children += child;
parent->str += child->str;
child->parent = parent;
}
}
/**
添加token
*/
void BooleanParser::addToken(Node *parent, const QString &str,
Node::Type type)
{
if (in.mid(pos, str.length()) == str) {
addChild(parent, new Node(type, str));
pos += str.length();
}
}
/**
token匹配
*/
bool BooleanParser::matchToken(const QString &str) const
{
return in.mid(pos, str.length()) == str;
}

booleanwindow.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef BOOLEANWINDOW_H
#define BOOLEANWINDOW_H
#include <QWidget>
class QLabel;
class QLineEdit;
class QTreeView;
class BooleanModel;
class BooleanWindow : public QWidget
{
Q_OBJECT
public:
BooleanWindow();
private slots:private slots:
void booleanExpressionChanged(const QString &expr);
private:
QLabel *label;
QLineEdit *lineEdit;
BooleanModel *booleanModel;
QTreeView *treeView;
};
#endif // BOOLEANWINDOW_H

booleanwindow.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <QtGui>
#include "booleanwindow.h"
#include "booleanmodel.h"
#include "booleanparser.h"
BooleanWindow::BooleanWindow()
{
//Label
label = new QLabel(tr("Boolean expression:"));
//LineEdit
lineEdit = new QLineEdit;
//BooleanModel
booleanModel = new BooleanModel(this);
//TreeView
treeView = new QTreeView;
treeView->setModel(booleanModel);
//signal and slot
connect(lineEdit, SIGNAL(textChanged(QString)), this,SLOT(booleanExpressionChanged(QString)));
//Layout
QGridLayout *layout = new QGridLayout;
layout->addWidget(label, 0 ,0);
layout->addWidget(lineEdit, 0 , 1);
layout->addWidget(treeView, 1, 0, 1, 2);
setLayout(layout);
setWindowTitle(tr("Boolean Parser"));
}
void BooleanWindow::booleanExpressionChanged(const QString &expr)
{
BooleanParser parser;
Node *rootNode = parser.parse(expr);
booleanModel->setRootNode(rootNode);
}

其他的可以去下载

下载地址:http://download.csdn.net/source/1529790">http://download.csdn.net/source/1529790

软件截图:

image

PS:最近比较郁闷.....

这个软件用于计算文件夹中图片所占空间大小

程序很短,直接看代码吧

main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <QtGui>
#include <iostream>
#include <string>
/**
计算文件中图片所占大小
*/
qlonglong imageSpaceCompute(const QString &path)
{
QDir dir(path);
qlonglong size = 0;
QStringList filters;
foreach(QByteArray format,QImageReader::supportedImageFormats())
filters += "*." + format;
foreach(QString file, dir.entryList(filters,QDir::Files)) //entryList 返回文件夹下满足条件的文件名列表
size += QFileInfo(dir,file).size();
//递归,计算子目录中的图片大小
foreach (QString subDir, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
size += imageSpaceCompute(path + QDir::separator() + subDir);
return size;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString path = QDir::currentPath();
std::cout << "Space used by imaged in" << qPrintable(path)
<< " and its subdirectories is " << (imageSpaceCompute(path) / 1024) << " KB" << std::endl;
return 0;
}

要是不能运行看看项目配置文件,这里附上我的

1
2
3
4
5
6
7
QT       = core gui xml
TARGET = ImageSpaceCompute
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app

SOURCES += main.cpp

软件截图:

image

最近学习 Qt4 的数据库编程方面,早上安装了下 MySQL,这里写 Qt4 连接 MySQL 的方法

首先,自己先去建立一个数据库名为,DB_Name

然后,自己可以尝试下连接,利用 mysql-admin 是个很好用的工具,保证数据连接是没有问题的,这里用的 Server Name 就用本地的吧(localhost)

保证数据库连接没问题以后,就可以参考下这下面的代码了(仅供参考,有问题请来信),我把它写成函数的形式,方便以后调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
bool createConnection()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");
db.setDatabaseName("DB_Name");
db.setUserName("root");
db.setPassword("123456");
if (!db.open()) {
QMessageBox::warning(0, QObject::tr("Database Error"),
db.lastError().text());
return false;
}
return true;
}

Sever Name:localhost 使用本地连接

数据库名:DB_Name

登录账户:root

密码:123456

这个还是练习项视图,用于浏览目录,可以添加新文件夹和删除文件或文件夹

directoryviewer.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#ifndef DIRECTORYVIEWER_H
#define DIRECTORYVIEWER_H
#include <QtGui/QDialog>
class QDialogButtonBox;
class QDirModel;
class QTreeView;
namespace Ui
{
class DirectoryViewer;
}
class DirectoryViewer : public QDialog
{
Q_OBJECT
public:
DirectoryViewer(QWidget *parent = 0);
~DirectoryViewer();
private slots:
void createDirectory();
void remove();
private:
Ui::DirectoryViewer *ui;
QTreeView *treeView;
QDirModel *model;
QDialogButtonBox *buttonBox;
};
#endif // DIRECTORYVIEWER_H

directoryviewer.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <QtGui>
#include "directoryviewer.h"
#include "ui_directoryviewer.h"
/**
构造函数
*/
DirectoryViewer::DirectoryViewer(QWidget *parent)
: QDialog(parent), ui(new Ui::DirectoryViewer)
{
ui->setupUi(this);
//model
model = new QDirModel;
model->setReadOnly(false);
model->setSorting(QDir::DirsFirst | QDir::IgnoreCase | QDir::Name);
//treeView
treeView = new QTreeView;
treeView->setModel(model);
treeView->header()->setStretchLastSection(true);
treeView->header()->setSortIndicator(0,Qt::AscendingOrder);
treeView->header()->setSortIndicatorShown(true);
treeView->header()->setClickable(true);
QModelIndex index = model->index(QDir::currentPath());
treeView->expand(index);
treeView->scrollTo(index);
treeView->resizeColumnToContents(0);
//ButtonBox
buttonBox = new QDialogButtonBox(Qt::Horizontal);
QPushButton *mkdirButton = buttonBox->addButton(tr("&Create Directory"),QDialogButtonBox::ActionRole);
QPushButton *removeButton = buttonBox->addButton(tr("&Remove"),QDialogButtonBox::ActionRole);
buttonBox->addButton(tr("&Quit"),QDialogButtonBox::AcceptRole);

//signal and slot
connect(mkdirButton,SIGNAL(clicked()),this,SLOT(createDirectory()));
connect(removeButton,SIGNAL(clicked()),this,SLOT(remove()));
connect(buttonBox,SIGNAL(accepted()),this,SLOT(accept()));
//Layout
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(treeView);
layout->addWidget(buttonBox);
setLayout(layout);
setWindowTitle(tr("Directory Viewer by Killua"));
}
/**
析构函数
*/
DirectoryViewer::~DirectoryViewer()
{
delete ui;
}
/**
文件夹创建
*/
void DirectoryViewer::createDirectory()
{
QModelIndex index = treeView->currentIndex();
if (!index.isValid())
return ;
QString dirName = QInputDialog::getText(this,tr("Create Directory"),tr("Directory Name"));
if (!dirName.isEmpty()) {
if (!model->mkdir(index,dirName).isValid())
QMessageBox::information(this,tr("Create Directory"),tr("Failed to create"));
}
}
/**
删除
*/
void DirectoryViewer::remove()
{
QModelIndex index =treeView->currentIndex();
if (!index.isValid())
return ;
bool ok;
if (model->fileInfo(index).isDir()) {
ok = model->rmdir(index);
} else {
ok = model->remove(index);
}
if (!ok)
QMessageBox::information(this,tr("Remove"),tr("Failed to remvoe"));
}

软件截图: image

这个主要练习项视图的显示并设置了 insert 和 delete 功能


listviewer.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#ifndef LISTVIEWER_H
#define LISTVIEWER_H
#include <QtGui/QDialog>
class QDialogButtonBox;
class QListView;
class QStringListModel;
namespace Ui
{
class ListViewer;
}
class ListViewer : public QDialog
{
Q_OBJECT
public:
ListViewer(const QStringList &itemList,QWidget *parent = 0);
~ListViewer();
QStringList itemList() const;
private slots:
void insert();
void del();
private:
Ui::ListViewer *ui;
QListView *listView;
QDialogButtonBox *buttonBox;
QStringListModel *model;
};
#endif // LISTVIEWER_H

listviewer.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <QtGui>
#include "listviewer.h"
#include "ui_listviewer.h"
ListViewer::ListViewer(const QStringList &itemList,QWidget *parent)
: QDialog(parent), ui(new Ui::ListViewer)
{
ui->setupUi(this);
//model
model = new QStringListModel(this);
model->setStringList(itemList);
//listView
listView = new QListView;
listView->setModel(model);
listView->setEditTriggers(QAbstractItemView::AnyKeyPressed | QAbstractItemView::DoubleClicked); //The QAbstractItemView class provides the basic functionality for item view classes.
//buttonBox
buttonBox = new QDialogButtonBox();
QPushButton *insertButton = buttonBox->addButton(tr("&Insert"),QDialogButtonBox::ActionRole); //ActionRole:Clicking the button causes changes to the elements within the dialog
QPushButton *deleteButton = buttonBox->addButton(tr("&Delete"),QDialogButtonBox::ActionRole);
buttonBox->addButton(QDialogButtonBox::Ok);
buttonBox->addButton(QDialogButtonBox::Cancel);
//signals and slots
connect(insertButton,SIGNAL(clicked()),this,SLOT(insert()));
connect(deleteButton,SIGNAL(clicked()),this,SLOT(del()));
connect(buttonBox,SIGNAL(accepted()),this,SLOT(accept()));
connect(buttonBox,SIGNAL(rejected()),this,SLOT(reject()));
//layout
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(listView);
layout->addWidget(buttonBox);
setLayout(layout);
}
ListViewer::~ListViewer()
{
delete ui;
}
QStringList ListViewer::itemList() const
{
return model->stringList();
}
void ListViewer::insert()
{
int row = listView->currentIndex().row();
model->insertRows(row, 1);
QModelIndex index=model->index(row); //This class is used as an index into item models derived from QAbstractItemModel.
//The index is used by item views, delegates, and selection models to locate an item in the model.
listView->setCurrentIndex(index);
listView->edit(index);
}
void ListViewer::del()
{
model->removeRows(listView->currentIndex().row(),1);
}

最近太忙了,都没怎么看 Qt 鄙视下自己....

不说了,放代码

symbolpicker.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#ifndef SYMBOLPICKER_H
#define SYMBOLPICKER_H
#include <QtGui/QDialog>
#include <QMap>
class QDialogButtonBox;
class QIcon;
class QListWidget;
namespace Ui
{
class SymbolPicker;
}
class SymbolPicker : public QDialog
{
Q_OBJECT
public:
SymbolPicker(const QMap<int,QString> &symbolMap,QWidget *parent = 0);
~SymbolPicker();
int selected() const {return id;}
void done(int result);
private:
Ui::SymbolPicker *ui;
QIcon iconForSymbol(const QString &symbolName);
QListWidget *listWidget;
QDialogButtonBox *buttonBox;
int id;
};
#endif // SYMBOLPICKER_H

symbolpicker.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include<QtGui>
#include "symbolpicker.h"
#include "ui_symbolpicker.h"
SymbolPicker::SymbolPicker(const QMap<int,QString> &symbolMap,QWidget *parent)
: QDialog(parent), ui(new Ui::SymbolPicker)
{
ui->setupUi(this);
id = -1; //设置id默认值
listWidget = new QListWidget;
listWidget->setIconSize(QSize(60,60));
QMapIterator<int,QString> i(symbolMap);
while(i.hasNext()) {
i.next();
QListWidgetItem *item = new QListWidgetItem(i.value(),listWidget);
item->setIcon(iconForSymbol(i.value()));
item->setData(Qt::UserRole,i.key());
}
buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok| QDialogButtonBox::Cancel);
connect(buttonBox,SIGNAL(accepted()),this,SLOT(accept()));
connect(buttonBox,SIGNAL(rejected()),this,SLOT(reject()));
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(listWidget);
layout->addWidget(buttonBox);
setLayout(layout);
setWindowTitle(tr("Symbol Picker"));
}
SymbolPicker::~SymbolPicker()
{
delete ui;
}
void SymbolPicker::done(int result)
{
id = -1;
if (result == QDialog::Accepted) {
QListWidgetItem *item = listWidget->currentItem();
if (item)
id = item->data(Qt::UserRole).toInt();
}
QDialog::done(result);
}
QIcon SymbolPicker::iconForSymbol(const QString &symbolName)
{
QString fileName = ":/images/" + symbolName.toLower();
fileName.replace(' ','-');
return QIcon(fileName);
}

symbolpicker.qrc (资源文件)

1
2
3
4
5
<RCC>
<qresource>
<file>images/killua.png</file>
</qresource>
</RCC>

刚开始 icon 显示一直有问题,后来配置了下资源文件就 OK 了...

用于正则表达式,通配符,完整匹配三种方式

stringmatch.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#ifndef STRINGMATCH_H
#define STRINGMATCH_H
#include <QtGui/QDialog>
class QComboBox;
class QLabel;
class QLineEdit;
class QListView;
class QSortFilterProxyModel;
class QStringListModel;
namespace Ui
{
class StringMatch;
}
class StringMatch : public QDialog
{
Q_OBJECT
public:
StringMatch(QWidget *parent = 0);
~StringMatch();
private slots:
void reapplyFilter();
private:
Ui::StringMatch *ui;
QStringListModel *sourceModel;
QSortFilterProxyModel *proxyModel;
QListView *listView;
QLabel *filterLabel;
QLabel *syntaxLabel;
QLineEdit *filterLineEdit;
QComboBox *syntaxComboBox;
};
#endif // STRINGMATCH_H

stringmatch.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <QtGui>
#include "stringmatch.h"
#include "ui_stringmatch.h"
StringMatch::StringMatch(QWidget *parent)
: QDialog(parent), ui(new Ui::StringMatch)
{
ui->setupUi(this);
QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());
QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8"));
//sourceModel
sourceModel = new QStringListModel(this);
sourceModel->setStringList(QColor::colorNames());
//proxyModel
proxyModel = new QSortFilterProxyModel(this);
proxyModel->setSourceModel(sourceModel);
proxyModel->setFilterKeyColumn(0);
//listView
listView = new QListView;
listView->setModel(proxyModel);
listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
//filter
filterLabel = new QLabel(tr("要匹配的字符串"));
filterLineEdit = new QLineEdit;
filterLabel->setBuddy(filterLineEdit);
//syntax
syntaxLabel = new QLabel("匹配方式选择");
syntaxComboBox = new QComboBox;
syntaxComboBox->addItem("正则表达式",QRegExp::RegExp); //A rich Perl-like pattern matching syntax. This is the default.
syntaxComboBox->addItem("通配符",QRegExp::Wildcard); //This provides a simple pattern matching syntax similar to that used by shells (command interpreters) for "file globbing".
syntaxComboBox->addItem("完全匹配",QRegExp::FixedString); //This is equivalent to using the RegExp pattern on a string in which all metacharacters are escaped using
//当filterLineEdit和syntaxComboBox
connect(filterLineEdit,SIGNAL(textChanged(const QString &)),this,SLOT(reapplyFilter()));
connect(syntaxComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(reapplyFilter()));
//布局
QGridLayout *layout = new QGridLayout;
layout->addWidget(listView,0,0,1,2);
layout->addWidget(filterLabel,1,0);
layout->addWidget(filterLineEdit,1,1);
layout->addWidget(syntaxLabel,2,0);
layout->addWidget(syntaxComboBox,2,1);
setLayout(layout);
setWindowTitle(tr("String Matching"));
}
StringMatch::~StringMatch()
{
delete ui;
}
void StringMatch::reapplyFilter()
{
QRegExp::PatternSyntax syntax = QRegExp::PatternSyntax(syntaxComboBox->itemData(
syntaxComboBox->currentIndex()).toInt());
QRegExp regExp(filterLineEdit->text(),Qt::CaseInsensitive,syntax);
proxyModel->setFilterRegExp(regExp);
}

软件截图: image


直到今天才把 Qt4 的中文乱码搞定太尴尬了.......鄙视下自己..... 只要程序中加入 QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale()); QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8"));

当然要看情况来说,你的环境可能是 GBK 或者其他的...

这个主要是编码的问题,我用的 Ubuntu,貌似 XP 就没有这个问题,蛮发下....

只要在程序种加上这两句:

1
2
QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());
QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8"));

具体编码要看具体环境了,可能是 GBK 或者 GB18030 或者其他的.....

PS:今天才搞懂,BS 自己阿....

今天晚上突然想到,前几天写那个 MDI Editor 少了拖拽功能支持,这里补充一下....

主要是对 Editor 类进行补充

在 editor.h 添加

1
2
3
//拖放
void dragEnterEvent(QDragEnterEvent *event);
void dropEvent(QDropEvent *event);

在 editor.cpp 添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
拖放的两个Event
*/
void Editor::dragEnterEvent(QDragEnterEvent *event)
{
if(event->mimeData()->hasFormat("text/uri-list"))
event->acceptProposedAction();
}
void Editor::dropEvent(QDropEvent *event)
{
QList<QUrl> urls = event->mimeData()->urls();
if(urls.isEmpty())
return ;
QString fileName = urls.first().toLocalFile();
if (fileName.isEmpty())
return ;
if(readFile(fileName))
setWindowTitle(tr("%1").arg(fileName));
}

OK.

PS:晚上才发现,我的工程名居然打错了..mdieditor 打成 mideditor 了...好尴尬...算了不改了,有不影响学习交流