QT学习笔记-1.QT主要的对象

说来惭愧学习c++很长时间了一直没有使用c++开发过软件界面
所以现在想认认真真的学习一个c++图形界面框架库
本来想学习Xwidget但是这个资料不大好找 有啥问题不好解决
那就学习QT吧

不说QT的优缺点,不说如何编译QT
从QT的主要库类开始吧
知道了基本的对象之后如果需要学习看看文档就知道了
如果需要编译QT的话再下个代码试着编译吧

QApplication 应用程序类                管理图形用户界面应用程序的控制流和主要设置
QLabel 标签类                                提供文本或者图像的显示
QPushButton 按钮类                      提供了命令按钮 按钮的一种
QButtonGroup 按钮组合类              按钮组 相关按钮的组合
QGroupBox 群组类                         一个有标题的组合框
QDateTimeEdit 日期时间编辑框类   
QLineEdit 行编辑框类                     单行文本编辑器
QTextEdit 文本编辑框类                  单页面多信息编辑器对象
QComboBox 组合框类
QProgressBar 进度条类
QLCDNumber 数字显示框类
QScrollBar 滚动条类
QSpinBox 微调框类
QSlider 滑动条类
QIconView 图标视图类
QListView 列表视图类
QListBox 列表框类

QTable 表格类
QValidator 有效性检查类
QImage 图像类
QMainWindow 主窗口类
QPopupMenu 弹出性菜单类
QMenuBar 菜单栏类
QToolButton 工具按钮类
QToolTip 提示类
QWhatsThis 这是什么类
QAction 动作类
QHBoxLayout 水平布局类
QVBoxLayout 垂直布局类
QGridLayout 表格布局类

QT对话框类
QMessageBox 消息对话框类
QProgressDialog 进度条对话框类
QWizard 向导对话框类
QFileDialog 文件对话框类
QColorDialog 颜色对话框类
QFontDialog 字体对话框类
QPrintDialog 打印对话框类

基本就这些对象了
要系统学习QT 还需要看看QT的slot系统,QT库类接口等
具体的学习就是看例子咯

QT学习笔记-2.QT窗体布局和皮肤加载

学习QT的一个原因是貌似QT做出来的界面比较绚丽
我倒想看看能做出来啥样子的

从QT窗体布局说起
凡是窗体布局无非就是如何摆放的问题
1.想当然如果摆放有2个方式一个是所见即所得,一个是使用布局管理器
先说后者吧
2.QT有好几种布局管理器无非就是啥子流式布局,格子布局等等
从这个层级上说软件界面都是布局嵌套的
3.布局和控件的关系
   一般是一个布局对应于一个控件容器(或者顶层控件)
   使用当前布局管理器加挂子控件(容器)即可
然后给当前控件挂上布局管理器即可
下面是一个简单的QT Layout的例子(从QT例子改的)

class Dialog : public QDialog
{
    Q_OBJECT
public:
    Dialog();
private:
    void createHorizontalGroupBox();

enum {button_number = 4};
    QGroupBox *groupbox;
    QPushButton *buttons[button_number];
    QDialogButtonBox *buttonBox;
};

实现如下:

#include <QtGui>

#include "dialog.h"

//! [0]
Dialog::Dialog()
{
    createHorizontalGroupBox();

buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok
                                     | QDialogButtonBox::Cancel);

connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
    connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));

QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(groupbox);
    mainLayout->addWidget(buttonBox);
    setLayout(mainLayout);

setWindowTitle(tr("LayoutTest"));
}

void Dialog::createHorizontalGroupBox()
{
    groupbox = new QGroupBox(tr("Layout Test"));
    QHBoxLayout *layout = new QHBoxLayout;

buttons[0] = new QPushButton(tr("Button1"));
    buttons[1] = new QPushButton(tr("Button2"));
    buttons[2] = new QPushButton(tr("Button3"));
    buttons[3] = new QPushButton(tr("Button4"));

for(int i = 0;i<button_number;i++)
        layout->addWidget(buttons[i]);
    groupbox->setLayout(layout);
}

几个知识点:
1.groupbox = new QGroupBox(tr("Layout Test")); 
Layout Test 是个文本这个无须解释
那tr呢?查查资料知道是为了支持多语言
先知道即可以后使用的话在具体查查吧
2.QDialogButtonBox是个什么东西
   看看最终的程序界面吧
   原来是对话框的确认和取消按钮
    再看信号槽函数无非就是绑定按钮到操作函数
    connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
    connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
    那accepted和accept函数有啥区别?
    看看文档
    accept函数的解释是:Hides the modal dialog and sets the result code to Accepted
  accpeted函数的解释是:This signal is emitted when the dialog has been accepted either

在说说QT皮肤
学习QT的主要目的就是想做做脸蛋好看好的软件界面
那就试试看吧
查到的QT有一个名叫QSS(CSS?)的文件可以原来换肤
那就改改看吧

#include <QApplication>
#include <QFile>
#include <QStyleFactory>
#include <QTextStream>
#include "dialog.h"

void setSkin(QApplication* const app, QString const &skinFile);

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    setSkin(&app ,"skin.qss");
    Dialog dialog;
    dialog.show();
    return app.exec();
}

void setSkin(QApplication* const app, QString const &skinFile)
{
    QFile qss(skinFile);
    qss.open(QFile::ReadOnly);
    app->setStyleSheet(qss.readAll());
    qss.close();
}

相应的QSS文件如下:

QPushButton 
 {
    color:red;
    background:url(setting.png)
 }

这里把PushButton的文本颜色设置为红色
同时把它的背景设置为图片stting.png

完了
PS:如果学习新知识?
囫囵吞枣比较适合快速学习

QT学习笔记-3.Codecs例子学习

QT自带的例子Codecs是一篇关于保存和载入不同编码文本的例子
其界面比较简单一个简单的单文档而已
有2个主要的对象
一个是MainWindow用于窗体主界面
另外一个是PreviewForm用于显示编码格式列表
1.其编码格式的获取部分代码如下:

QMap<QString, QTextCodec *> codecMap;
    QRegExp iso8859RegExp("ISO[- ]8859-([0-9]+).*");

foreach (int mib, QTextCodec::availableMibs()) {
        QTextCodec *codec = QTextCodec::codecForMib(mib);

QString sortKey = codec->name().toUpper();
        int rank;

if (sortKey.startsWith("UTF-8")) {
            rank = 1;
        } else if (sortKey.startsWith("UTF-16")) {
            rank = 2;
        } else if (iso8859RegExp.exactMatch(sortKey)) {
            if (iso8859RegExp.cap(1).size() == 1)
                rank = 3;
            else
                rank = 4;
        } else {
            rank = 5;
        }
        sortKey.prepend(QChar('0' + rank));

codecMap.insert(sortKey, codec);
    }
    codecs = codecMap.values();

通过使用foreach循环来获取支持的编码格式并保存
不过看上去foreach (int mib, QTextCodec::availableMibs())有点奇怪
查查资料 
解释是foreach(variables ,container)关键字是Qt对c++的一个扩展,主要用于按顺序历经容器(container)中的对象
2关于文件菜单的生成和设置
菜单的构造
一个例子
saveAsMenu = new QMenu(tr("&Save As"), this);这里有2个参数一个是菜单显示文另外一个是当前窗体指针
然后就可以加载子菜单,设置分隔符,设置事件响应等操作了
例子为:

fileMenu = new QMenu(tr("&File"), this);
    fileMenu->addAction(openAct);
    fileMenu->addMenu(saveAsMenu);
    fileMenu->addSeparator();
    fileMenu->addAction(exitAct);

那如何绑定菜单到当前窗体呢
如下:

menuBar()->addMenu(fileMenu);
menuBar()->addSeparator();
menuBar()->addMenu(helpMenu);

menuBar()是QmainWindow的成员函数用于获取窗体菜单项指针
3.QT对象QAction
QT文档对QAction的解释是可以抽象用户接口对象-可以插入控件
例子如下:

openAct = new QAction(tr("&Open"), this);
    openAct->setShortcuts(QKeySequence::Open);
    connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
无非就是对象声明,设置快捷键,链接函数和响应而已
4.窗体设置
    setWindowTitle(tr("Codecs"));

resize(500, 400);

5.消息对话框
    QMessageBox::about(this, tr("About Codecs"),
            tr("The <b>Codecs</b> example demonstrates how to read and write "
               "files using various encodings."));

QT学习笔记-4.信号与插槽

本文主要是对C++ GUI Programming with Qt4一书 Signals and Slots in Depth 部分的翻译
信号与插槽机制是Qt编程的基础.它可以绑定对象而不需要对象之间彼此了解。
槽类似于c++中的成员函数他可以是虚拟的,可重载的,私有的,公开的,受保护的。
不同点式槽可以链接到信号。通过这种方式可以在每次信号发射的的时候做到调用槽函数
connect()语句是这样的

connect(sender, SIGNAL(signal), receiver, SLOT(slot));

在这里sender和receiver是指向信号对象和槽对象的指针。宏SIGNAL()和SLOTS()负责转换他们的参数到字符串。

当然一个信号可以连接到多个槽(似乎都是这样的)

connect(slider, SIGNAL(valueChanged(int)),
        spinBox, SLOT(setValue(int)));
connect(slider, SIGNAL(valueChanged(int)),
        this, SLOT(updateStatusBarIndicator(int)));

同样多个信号可以连接到单个槽
例如:

connect(lcd, SIGNAL(overflow()),
        this, SLOT(handleMathError()));
connect(calculator, SIGNAL(divisionByZero()),
        this, SLOT(handleMathError()));

除此之外信号可以连接到其他信号(见过的其他插槽系统似乎不大可以?)

connect(lineEdit, SIGNAL(textChanged(const QString &)),
        this, SIGNAL(updateRecord(const QString &)));

需要指出的是信号信号链接和信号插槽连接时不同的
既然信号和插槽可以连接那么他们应该可以断开,如下:

disconnect(lcd, SIGNAL(overflow()),
           this, SLOT(handleMathError()));

一个简单的例子:

class Employee : public QObject
{
    Q_OBJECT
public:
    Employee() { mySalary = 0; }
    int salary() const { return mySalary; }
public slots:
    void setSalary(int newSalary);
signals:
    void salaryChanged(int newSalary);
private:
    int mySalary;
};
void Employee::setSalary(int newSalary)
{
    if (newSalary != mySalary) {
        mySalary = newSalary;
        emit salaryChanged(mySalary);
    }
}

说明
关键字 public slots:和signals
他们用于修饰插槽函数和信号函数
至于信号的反射通过关键字 emit来实现

通过本文基本掌握了QT的信号插槽机制

QT学习笔记-5.QT容器和算法

本文涉及QT中的容器对象系列
一容器
QVector类似stl中的vector插入尾部数据速度很快
基本例子如下:
QVector<double> vect(3);
vect[0] = 1.0;
vect[1] = 0.540302;
vect[2] = -0.416147;
这样也可以
QVector<double> vect;
vect.append(1.0);
vect.append(0.540302);
vect.append(-0.416147);
另外也可以通过流
vect << 1.0 << 0.540302 << -0.416147;
2.QLinkedList没有提供[]操纵
随机访问速度很慢
3.QList<T>序列容器是一种数组链表它具有前2者的大部分操作支持随机访问
在容器头部尾部插入数据很迅速
4.QStringList是QList<QString>的子类提供以下操作
排序,过滤,正则表达式处理等
5.QStack<T> 提供push,pop,top等操作
6.Queue<T> QT的队列模板
7.QMap<T,V>
基本操作如下:
QMap<QString, int> map;
map.insert("eins", 1);
map.insert("sieben", 7);
map.insert("dreiundzwanzig", 23);
当然也可以这样插入数据
map["eins"] = 1;
map["sieben"] = 7;
map["dreiundzwanzig"] = 23;
但是这样做有一个问题那就是会生成空值
为了不出现这样的结果可以使用成员函数value()来代替[]来获取数据,如果对于键不存在则返回默认的对象值
8.QHash<T,V> 使用散列存储键值对
二通用算法
需要说明的是QT中的容器是stl风格的,这意味着可以使用Stl中的算法。
当然在QT库中QtAlgorithm文件包含了基本的算法模板
主要的函数有
qFind-查找给定元素在容器中的位置类似std::find
qBinaryFind - 类似qFind 需要查找元素有序排列
qFill-类似std::fill 使用给定元素填充容器
qCopy,qSort..
qDeleteAll-函数对容器中的每个元素做删除处理

基本的容器和算法就这么多了
其实熟悉stl的话学习这个上手很快的

QT学习笔记-6.QApplication和基本控件的使用

接上文,这篇学学QT中基本控件的使用和QApplication对象
1.什么是QApplication?
文档说明:The QApplication class manages the GUI application's control flow and main settings.
Application类管理GUI程序控制流和主要参数设置
QApplication继承于QCoreApplication。后者提供了控制台程序的事件流
2.基本控件的使用例子:

#include <QApplication>
#include <QLabel>
#include <QPalette>

#define QT_HTML

QLabel* label = NULL;

void initlabel()
{
#ifndef QT_HTML
    label = new QLabel("Hello Qt!");
#else
    label = new QLabel("<h2><i>Hello</i><font color=red>Qt!</font></h2>");
#endif
    //! set size
    label->setBaseSize(64,48);
    //! set alignment
    label->setAlignment(Qt::AlignHCenter);
    
    //! sht background color
    QColor bk(100,100,125);
    QPalette palette(bk);
    label->setPalette(palette);
}

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    app.setApplicationName("QT Test");
    initlabel();
    label->show();
    return app.exec();
}

QLabel是QT中的标签控件它具有控件的一般属性比如设置大小setBaseSite,设置对齐格式,当然也可以设置背景色或者图片-这都是通过QPalette调色板来实现的
需要说明的是QT中的控件文本可以使用Html语法的文本来操作具体如上。
那觉这个功能比较给力!
3.那么什么是QPalette?
QPalette负责控制控件状态的颜色组-注意是控件状态。
那么对一个控件每个状态的颜色都可以是不一样的咯
至于QPalette的详细功能和使用方法以后需要的时候再看吧
4.基本的信号链接使用例子

#include <QApplication>
#include <QPushButton>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QPushButton *button = new QPushButton("Quit");
    //! when click button, app exit.
    QObject::connect(button, SIGNAL(clicked()),&app, SLOT(quit()));
    button->show();
    return app.exec();
}

5.一个复杂点的例子

#include <QApplication>
#include <QHBoxLayout>
#include <QSlider>
#include <QSpinBox>
#include <QIcon>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QWidget* widget = new QWidget;
    QIcon icon("config.png");
    widget->setWindowIcon(icon);
    widget->setWindowTitle("Using QT");
            
    QSlider* slider = new QSlider(widget);
    slider->setRange(0,99);

QSpinBox* spinbox = new QSpinBox(widget);
    spinbox->setRange(0,99);
    
    widget->show();
    return app.exec();
}

编译运行可以看出QWidget中默认的布局管理器是竖直向下排列的
在QT中可以通过setWindowIcon来设置窗体图标
通过setWindowTitle设置窗体标题
6.加上布局管理器和信号连接的话代码大致应该是这个样子

#include <QApplication>
#include <QHBoxLayout>
#include <QSlider>
#include <QSpinBox>
#include <QIcon>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QWidget* widget = new QWidget;
    QIcon icon("config.png");
    widget->setWindowIcon(icon);
    widget->setWindowTitle("Using QT");

QSlider* slider = new QSlider(widget);
    slider->setRange(0,99);

QSpinBox* spinbox = new QSpinBox(widget);
    spinbox->setRange(0,99);

QHBoxLayout* layout = new QHBoxLayout;
    layout->addWidget(spinbox);
    //! adjust slider's direction
    slider->setOrientation(Qt::Horizontal);
    layout->addWidget(slider);

spinbox->setValue(28);

//! connect signals and slots
    QObject::connect(spinbox, SIGNAL(valueChanged(int)),slider,SLOT(setValue(int)));
    QObject::connect(slider,SIGNAL(valueChanged(int)),spinbox,SLOT(setValue(int)));

widget->setLayout(layout);
    widget->show();
    return app.exec();
}

需要说明的是在这里QSlider,QPinBox控件是互动
编译程序并运行界面如下:

这是关于QT的第六篇笔记
总结下吧
QT功能还是很强大贴心的
比较容易上手
不过有2点我感觉不大舒服的地方是对这个变量命名格式有点不大喜欢
比如setValue我喜欢写成SetValue.
仅此而已

QT学习笔记-7.QString和QByteArray

1.QString
在c++标准库中有2种类型的字符串char*和std::string
QT则提供了对象QString
QString除了具备字符串对象一般功能函数之外还提供了自己特有的功能比如:
str.sprintf("%s %.1f%%", "perfect competition", 100.0); ---格式化输出
当然也可以使用匿名形式
str = QString("%1 %2 (%3s-%4s)").arg("permissive").arg("society").arg(1950).arg(1970);
%1,%2,%3是占位符
另外QString还提供了一系列类型类型装换函数比如:
str = QString::number(59.6);
str.setNum(59.6);
当然还有其他功能
下面是具体的测试例子:
#include <QtCore/QCoreApplication>
#include <QString>
#include <QtDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc,  argv);
    QString str;
    str.append("Hello QT");
    qDebug()<<str.left(3);
    qDebug()<<str.right(3);
    qDebug()<<str.mid(2,2);
    qDebug()<<str.mid(2);
    qDebug()<<str.indexOf("QT");
    qDebug()<<str.startsWith("Hello");
    qDebug()<<str.toLower();
    str.replace(" ","O(∩_∩)O~");
    qDebug()<<str;
    str.insert(0,"....");
    qDebug()<<str;
    str.remove(0,3);
    qDebug()<<str;
    str = QString("%1%2%3").arg("1").arg(2).arg("3");
    qDebug()<<str;
    return a.exec();
}

当然还有其他它功能

2.QByteArray
QByteArray是比特数组
为了掌握它的基本功能还是测试下功能大致就知道了
#include <QtCore/QCoreApplication>
#include <QByteArray>
#include <QtDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc,  argv);
    QByteArray arr;
    arr.append("123");
    qDebug()<<arr.at(2);
    arr = "lots\t of\nwhitespace\r\n ";
    qDebug()<<arr;
    qDebug()<<arr.simplified();
    qDebug()<<arr;
    arr.chop(3);
    qDebug()<<arr;
    qDebug()<<arr.count();
    qDebug()<<arr.isEmpty();
    qDebug()<<arr.isNull();
    arr.fill(244,10);
    qDebug()<<arr;
    return a.exec();
}

QT学习笔记-8.查找文件对话框

QT学习笔记-8.查找文件对话框

只所以选择这个QT自带的例子有2个原因
1是界面简单容易理解
2是当点击more按键会动态改变窗体出现高级选项(我想知道这个是如何做到的)

基本代码如下:

#ifndef FINDDIALOG_H
#define FINDDIALOG_H

#include <QDialog>

QT_BEGIN_NAMESPACE
class QCheckBox;
class QDialogButtonBox;
class QGroupBox;
class QLabel;
class QLineEdit;
class QPushButton;
QT_END_NAMESPACE

class FindDialog : public QDialog
{
    Q_OBJECT

public:
    FindDialog(QWidget *parent = 0);

private:
    QLabel *label;
    QLineEdit *lineEdit;
    QCheckBox *caseCheckBox;
    QCheckBox *fromStartCheckBox;
    QCheckBox *wholeWordsCheckBox;
    QCheckBox *searchSelectionCheckBox;
    QCheckBox *backwardCheckBox;
    QDialogButtonBox *buttonBox;
    QPushButton *findButton;
    QPushButton *moreButton;
    QWidget *extension;
};

#endif

.cpp
#include <QtGui>
#include "finddialog.h"

FindDialog::FindDialog(QWidget *parent)
    : QDialog(parent)
{
    label = new QLabel(tr("Find &what:"));
    lineEdit = new QLineEdit;
    //! 这个成员函数的作用是当点击控件快捷键则把响应发送到Buddy控件
    label->setBuddy(lineEdit);

caseCheckBox = new QCheckBox(tr("Match &case"));
    fromStartCheckBox = new QCheckBox(tr("Search from &start"));
    fromStartCheckBox->setChecked(true);

findButton = new QPushButton(tr("&Find"));
    findButton->setDefault(true);

moreButton = new QPushButton(tr("&More"));
    moreButton->setCheckable(true);

//moreButton->setAutoDefault(false);

//! 又是对话框按钮盒,不过这次使用和上次有点区别 其子按钮是加上去的
    buttonBox = new QDialogButtonBox(Qt::Vertical);
    buttonBox->addButton(findButton, QDialogButtonBox::ActionRole);
    buttonBox->addButton(moreButton, QDialogButtonBox::ActionRole);

extension = new QWidget;

wholeWordsCheckBox = new QCheckBox(tr("&Whole words"));
    backwardCheckBox = new QCheckBox(tr("Search &backward"));
    searchSelectionCheckBox = new QCheckBox(tr("Search se&lection"));

//! 绑定时间(需要注意的是SINGLA,SLOT中的函数必须是形式完备的)
    connect(moreButton, SIGNAL(toggled(bool)), extension, SLOT(setVisible(bool)));

//! 扩展控件部分(使用QVBox布局)
    QVBoxLayout *extensionLayout = new QVBoxLayout;
    extensionLayout->setMargin(0);
    extensionLayout->addWidget(wholeWordsCheckBox);
    extensionLayout->addWidget(backwardCheckBox);
    extensionLayout->addWidget(searchSelectionCheckBox);
    extension->setLayout(extensionLayout);

//! 文本框和搜索键
    QHBoxLayout *topLeftLayout = new QHBoxLayout;
    topLeftLayout->addWidget(label);
    topLeftLayout->addWidget(lineEdit);

//! 辅助控件组
    QVBoxLayout *leftLayout = new QVBoxLayout;
    leftLayout->addLayout(topLeftLayout);
    leftLayout->addWidget(caseCheckBox);
    leftLayout->addWidget(fromStartCheckBox);
    leftLayout->addStretch(1);

//! 主布局使用格子管理器
    QGridLayout *mainLayout = new QGridLayout;
    //! 设置大小不能更改
    mainLayout->setSizeConstraint(QLayout::SetFixedSize);
    //! 把LeftLayout管理器放在左上角即0,0位置处
    mainLayout->addLayout(leftLayout, 0, 0);
    mainLayout->addWidget(buttonBox, 0, 1);
    mainLayout->addWidget(extension, 1, 0);
    setLayout(mainLayout);

setWindowTitle(tr("Extension"));

extension->setVisible(false);
}

需要说明的是
#include <QtGui>是包含所有的GUI控件头文件
我们不再需要
#include <QLabel>
#include <QEdit>

不过看看代码还真应了那句话复杂界面都是布局管理器堆积出来的
另外注意这句话
mainLayout->addWidget(extension, 1, 0);
把extension放在格子管理器的1,0位置
如果注销掉这句话可以看看出来的界面是什么样子的

最后要说的就是extension->setVisible(false);
在开始我们把exntension控件设置为隐藏状态
当然也可以使用函数hide().
由于之前绑定了more按键和extension,
我们就可以通过点击more按键来显示和隐藏extension控件了

QT学习笔记-9.Dock Widget例子学习

这是第9篇学习QT的例子
本文主要学习自带的Dock Widget例子
这个例子主要包含以下QT控件
1.Dock
2.Menu
3.ToolBar

1.看看例子还是说QMainWindow吧
什么是QMainWindow?
A main window provides a framework for building an application's user interface. Qt has QMainWindow and its related classes for main window management. QMainWindow has its own layout to which you can add QToolBars, QDockWidgets, QDockBars,QDockWidgets, a QStatusBar.

总而言之:QMainWindow提供构建应用程序接口的框架。QMainWindow提供独有的布局结构以便于用户加入QToolBar,QDockWidgets,QDockBars和QStatusBar.

2.使用自定义对象从QT对象继承的方法
除了必要的 :public QTObject
还要加入宏Q_OBJECT
如果必要加入槽,信号函数
一个例子是:

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow();

private slots:
    void newLetter();
    void save();
    void print();
    void undo();
    void about();
    void insertCustomer(const QString &customer);
    void addParagraph(const QString ¶graph);

3.状态栏
设置状态栏信息的函数
例子:

statusBar()->showMessage(tr("Ready"));

4.文件打开和保存对话框

QString fileName = QFileDialog::getSaveFileName(this,
                        tr("Choose a file name"), ".",
                        tr("HTML (*.html *.htm)"));

5.再说下QAction

newLetterAct = new QAction(QIcon(":/images/new.png"), tr("&New Letter"),
                               this);
    newLetterAct->setShortcuts(QKeySequence::New);
    newLetterAct->setStatusTip(tr("Create a new form letter"));
    connect(newLetterAct, SIGNAL(triggered()), this, SLOT(newLetter()));

通过调用setStatusTip可以设置action提示信息
6.QTextDocument对象
原文解释:
The QTextDocument class holds formatted text that can be viewed and edited using a QTextEdit.
通过QTextEdit的document可以获取QTextDocument对象
假定需要响应文档撤销事件
一个可能的例子就是:

void MainWindow::undo()
{
    QTextDocument *document = textEdit->document();
    document->undo();
}

7.QTextCursor
The QTextCursor class offers an API to accDuess and modify QTextDocuments.
我们就可以得出QTextCursor访问和修改QTextDocument,QTextDocumnt显示QTextEdit内容文本。
8.QDockWidget
The QDockWidget class provides a widget that can be docked inside a QMainWindow floated as a top-level window on the desktop.
关于Dock的用法如下:
设置Dock为左右结构

dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);

设置Dock内容控件
dock->setWidget(customerList);
把这个dock放在窗体右边
addDockWidget(Qt::RightDockWidgetArea, dock);
9.这个例子还有其他的对象比如QListWidget以后再看吧

不过这一篇感觉有几个疑惑的地方
比如:

QDockWidget *dock = new QDockWidget(tr("Customers"), this);
    dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
    customerList = new QListWidget(dock);
    customerList->addItems(QStringList()
            << "John Doe, Harmony Enterprises, 12 Lakeside, Ambleton"
            << "Jane Doe, Memorabilia, 23 Watersedge, Beaton"
            << "Tammy Shea, Tiblanka, 38 Sea Views, Carlton"
            << "Tim Sheen, Caraba Gifts, 48 Ocean Way, Deal"
            << "Sol Harvey, Chicos Coffee, 53 New Springs, Eccleston"
            << "Sally Hobart, Tiroli Tea, 67 Long River, Fedula");
    dock->setWidget(customerList);
    addDockWidget(Qt::RightDockWidgetArea, dock);
    viewMenu->addAction(dock->toggleViewAction());

dock = new QDockWidget(tr("Paragraphs"), this);

其中的dock new了2次并没有调用相应的delete.
不知道QT具体是如何实现的
另外在QT的例子中在程序结束的时候并没有销毁new出来的指针
不知道QT有内在机制保证内存不会泄露还是?

QT学习笔记-10.使用QT开发软件(1)

这是学习QT的第10篇文章
现在总算入门了
要想快速学习新的知识一个是要多看还有一个是要多练
本篇就是使用QT开发软件的开始

不过只是开始,我并不打算弄一个完完整整的例子
而是通过迭代式的循序渐进的方式一步一步完善软件

所以现在做出来的只是一个毛胚而已
首先上代码:

#include <QtGui/QMainWindow>

QT_BEGIN_NAMESPACE
class QAction;
class QToolBar;
class QMenu;
class QWidget;
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
public:
    void CreateAction();
    void CreateMenu();
    void CreateToolBar();
private slots:
    void home();
    void about();
    void setting();
    void running();

private:
    QMenu* setting_;
    QMenu* home_;
    QMenu* running_;
    QMenu* about_;

QToolBar* settingbar;
    QToolBar* homebar;
    QToolBar* runningbar;
    QToolBar* aboutbar;

QAction*  settingaction;
    QAction*  homeaction;
    QAction*  runningaction;
    QAction*  aboutaction;
};

.cpp
本文没有多少新的内容
需要说的2点:
1.qrc文件
这是QT的资源文件
我们可以把图标通过资源文件的方式包含进程序里面
本文的qrc内容如下:

<!DOCTYPE RCC><RCC version="1.0">
<qresource>
    <file>images/home.png</file>
    <file>images/running.png</file>
    <file>images/about.png</file>
    <file>images/setting.png</file>
    <file>images/logo.png</file>
</qresource>
</RCC>

那么使用的时候就可以这样调用了:
QIcon(":/images/home.png")
注意字符串最前面是一个冒号!
2.menuBar()和addToolBar的问题
menuBar()是QWidget中用于获取控件菜单栏的函数
addToolBar是增加工具条到控件的函数如果没有调用menuBar也没有调用addToolBar那可以认为控件是又没菜单项和工具条的
在这里我的感觉是既然menuBar是获取控件菜单项的函数,那为什么没有对应的toolBar?或者有addToolBar而无对于德addMenu?
从命名风格上上看我们还是希望程序命名尽可能一致的,这样可以减少使用者的记忆量。
--------当然这也行有这样写的理由
3.QT中打开给定网页链接的方法:

const QUrl url("http://www.cppblog.com/gaimor/");
    QDesktopServices::openUrl(url);

3.至于本程序文最终界面如下:

可以看出由于没有设置其他控件 导致程序界面没有被展开

QT学习笔记-11.styles例子学习

Styles是QT自带的例子 - 主要展示的是QT程序界面风格方面的编程知识
1.程序调色板的获取

使用QApplication中的静态函数
QApplication::palette

palette有2个版本一个是给定的调色板,另外一个给定的调色板
对应的调用QApplication::setPalette就可以设置新的程序调色板
如果使用自定义的Palette就可以达到修改界面色调的目的
比如:
2.QStyleFactory对象
The QStyleFactory class creates QStyle objects.
可以通过静态函数QStyleFactory::key()获取工厂所支持的风格名字列表(注意是列表,返回类型是QStringList)
当然可以通过函数cerate来生成新的风格指针
3.QComboBox 组合框
主要函数有以下几个:
通过函数addItem增加新项
通过addItems增加新项列表
通过插槽绑定就可以传递响应了:

connect(combobox,SIGNAL(activated(QString)),this, SLOT(changeComBox(QString)));

其他三个可能会用到的函数

currentIndex,count, currentText

4.QT计时器
拿例子说下:

QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(advanceProgressBar()));
    timer->start(1000);

首先构造一个计时器 然后绑定计时器对象和槽函数
之后启用计时器-每隔1秒钟调用advaceProressBar函数
如果想停止计时器则调用stop函数即可
5.QProgressBar进度条对象
基本的函数就那些
设置方向,当前值,最大值最小值,文本,可见性等等

progressBar = new QProgressBar;
progressBar->setRange(0, 10000);
progressBar->setValue(0);

其槽函数为

valueChanged ( int value )

6.单选按钮QRodioButton
例子如下

topLeftGroupBox = new QGroupBox(tr("Group 1"));
    radioButton1 = new QRadioButton(tr("Radio button 1"));
    radioButton2 = new QRadioButton(topLeftGroupBox);
    radioButton2->setText(tr("Radio button 2"));
    radioButton3 = new QRadioButton(tr("Radio button 3"));
    radioButton1->setChecked(true);
    layout->addWidget(radioButton1);
    layout->addWidget(radioButton2);
    layout->addWidget(radioButton3);

似乎没什么可说的
7.QTableWidget控件
The QTableWidget class provides an item-based table view with a default model.
需要说明的是如果要使用自定义类型,则需要使用QTableView而非QTableWidget.

tableWidget = new QTableWidget(this);
     tableWidget->setRowCount(10);
     tableWidget->setColumnCount(5);

不过感觉以后不会使用这个对象
8.QLineText
QT的单行输入控件
具体函数有(似乎不需要说功能了)

QString text() const;
QString displayText() const;
int maxLength() const;
void setMaxLength(int);
bool isReadOnly() const;
void setReadOnly(bool);
bool isModified() const;
void setModified(bool);

9.Q_INIT_RESOURCE(styles);
加载资源文件
styles.qrc

QT学习笔记-12.一个定制的QPlastiqueStyle例子

代码如下:

class lmmsStyle : public QPlastiqueStyle
{
public:
    lmmsStyle();
    virtual ~lmmsStyle() 
    {
    }

virtual QPalette standardPalette( void ) const;

virtual void drawComplexControl(
                ComplexControl control,
                const QStyleOptionComplex * option,
                    QPainter *painter,
                        const QWidget *widget ) const;
    virtual void drawPrimitive( PrimitiveElement element,
                    const QStyleOption *option,
                    QPainter *painter,
                    const QWidget *widget = 0 ) const;

virtual int pixelMetric( PixelMetric metric,
                    const QStyleOption * option = 0, 
                    const QWidget * widget = 0 ) const;

} ;

实现为:
lmmsStyle::lmmsStyle():

QPlastiqueStyle()

{

//QFile file("resources:style.css");

//file.open( QIODevice::ReadOnly);

//qApp->setStyleSheet(file.readAll());

qApp->setPalette(standardPalette());

}

QPalette lmmsStyle::standardPalette(void)const

{

QPalette pal = QPlastiqueStyle::standardPalette();

pal.setColor( QPalette::Background, QColor( 172, 176, 188 ) );

pal.setColor( QPalette::WindowText, QColor( 240, 240, 240 ) );

pal.setColor( QPalette::Base, QColor( 128, 128, 128 ) );

pal.setColor( QPalette::Text, QColor( 224, 224, 224 ) );

pal.setColor( QPalette::Button, QColor( 172, 176, 188 ) );

pal.setColor( QPalette::Shadow, QColor( 30, 30, 30 ) );

pal.setColor( QPalette::ButtonText, QColor( 255, 255, 255 ) );

pal.setColor( QPalette::BrightText, QColor( 20, 255, 20 ) );

pal.setColor( QPalette::Highlight, QColor( 204, 204, 204 ) );

pal.setColor( QPalette::HighlightedText, QColor( 0, 0, 0 ) );

return(pal);

}

void lmmsStyle::drawComplexControl(ComplexControl control,

const QStyleOptionComplex * option,

QPainter *painter,

const QWidget *widget ) const

{

// fix broken titlebar styling on win32

if( control == CC_TitleBar )

{

const QStyleOptionTitleBar * titleBar =

qstyleoption_cast<const QStyleOptionTitleBar *>(option );

if( titleBar )

{

QStyleOptionTitleBar so( *titleBar );

so.palette = standardPalette();

so.palette.setColor( QPalette::HighlightedText,

( titleBar->titleBarState & State_Active ) ?

QColor( 205, 205, 205 ) :

QColor( 192, 212, 152 ) );

so.palette.setColor( QPalette::Text,

QColor( 74, 74, 74 ) );

QPlastiqueStyle::drawComplexControl( control, &so,

painter, widget );

return;

}

}

QPlastiqueStyle::drawComplexControl( control, option, painter, widget );

}

void lmmsStyle::drawPrimitive( PrimitiveElement element,

const QStyleOption *option, QPainter *painter,

const QWidget *widget) const

{

if( element == QStyle::PE_Frame ||

element == QStyle::PE_FrameLineEdit ||

element == QStyle::PE_PanelLineEdit )

{

const QRect rect = option->rect;

QColor black = QColor( 10, 10, 10 );

QColor shadow = option->palette.shadow().color();

QColor highlight = option->palette.highlight().color();

int a100 = 165;

int a75 = static_cast<int>( a100 * .75 );

int a50 = static_cast<int>( a100 * .6 );

int a25 = static_cast<int>( a100 * .33 );

QLine lines[4];

QPoint points[4];

// black inside lines

// 50%

black.setAlpha(a100);

painter->setPen(QPen(black, 0));

lines[0] = QLine(rect.left() + 2, rect.top() + 1,

rect.right() - 2, rect.top() + 1);

lines[1] = QLine(rect.left() + 2, rect.bottom() - 1,

rect.right() - 2, rect.bottom() - 1);

lines[2] = QLine(rect.left() + 1, rect.top() + 2,

rect.left() + 1, rect.bottom() - 2);

lines[3] = QLine(rect.right() - 1, rect.top() + 2,

rect.right() - 1, rect.bottom() - 2);

painter->drawLines(lines, 4);

// black inside dots

black.setAlpha(a50);

painter->setPen(QPen(black, 0));

points[0] = QPoint(rect.left() + 2, rect.top() + 2);

points[1] = QPoint(rect.left() + 2, rect.bottom() - 2);

points[2] = QPoint(rect.right() - 2, rect.top() + 2);

points[3] = QPoint(rect.right() - 2, rect.bottom() - 2);

painter->drawPoints(points, 4);

// outside lines - shadow

// 100%

shadow.setAlpha(a75);

painter->setPen(QPen(shadow, 0));

lines[0] = QLine(rect.left() + 2, rect.top(),

rect.right() - 2, rect.top());

lines[1] = QLine(rect.left(), rect.top() + 2,

rect.left(), rect.bottom() - 2);

painter->drawLines(lines, 2);

// outside corner dots - shadow

// 75%

shadow.setAlpha(a50);

painter->setPen(QPen(shadow, 0));

points[0] = QPoint(rect.left() + 1, rect.top() + 1);

points[1] = QPoint(rect.right() - 1, rect.top() + 1);

painter->drawPoints(points, 2);

// outside end dots - shadow

// 50%

shadow.setAlpha(a25);

painter->setPen(QPen(shadow, 0));

points[0] = QPoint(rect.left() + 1, rect.top());

points[1] = QPoint(rect.left(), rect.top() + 1);

points[2] = QPoint(rect.right() - 1, rect.top());

points[3] = QPoint(rect.left(), rect.bottom() - 1);

painter->drawPoints(points, 4);

// outside lines - highlight

// 100%

highlight.setAlpha(a75);

painter->setPen(QPen(highlight, 0));

lines[0] = QLine(rect.left() + 2, rect.bottom(),

rect.right() - 2, rect.bottom());

lines[1] = QLine(rect.right(), rect.top() + 2,

rect.right(), rect.bottom() - 2);

painter->drawLines(lines, 2);

// outside corner dots - highlight

// 75%

highlight.setAlpha(a50);

painter->setPen(QPen(highlight, 0));

points[0] = QPoint(rect.left() + 1, rect.bottom() - 1);

points[1] = QPoint(rect.right() - 1, rect.bottom() - 1);

painter->drawPoints(points, 2);

// outside end dots - highlight

// 50%

highlight.setAlpha(a25);

painter->setPen(QPen(highlight, 0));

points[0] = QPoint(rect.right() - 1, rect.bottom());

points[1] = QPoint(rect.right(), rect.bottom() - 1);

points[2] = QPoint(rect.left() + 1, rect.bottom());

points[3] = QPoint(rect.right(), rect.top() + 1);

painter->drawPoints(points, 4);

}

else

{

QPlastiqueStyle::drawPrimitive( element, option, painter,

widget );

}

}

int lmmsStyle::pixelMetric( PixelMetric _metric, const QStyleOption * _option,

const QWidget * _widget ) const

{

switch( _metric )

{

case QStyle::PM_ButtonMargin:

return 3;

case QStyle::PM_ButtonIconSize:

return 20;

case QStyle::PM_ToolBarItemMargin:

return 1;

case QStyle::PM_ToolBarItemSpacing:

return 2;

case QStyle::PM_TitleBarHeight:

return 24;

default:

return QPlastiqueStyle::pixelMetric( _metric, _option,

_widget );

}

}

QT学习笔记-13.一个简单的用户注册对话框

还不太完善

#ifndef REGISTER_DLG_H
#define REGISTER_DLG_H

#include <QtGui/QDialog>
#include <QtGui/QVBoxLayout>
#include <QtGui/QHBoxLayout>
#include <QtGui/QGridLayout>
#include <QtGui/QLabel>
#include <QtGui/QLineEdit>
#include <QtGui/QPushButton>

class RegisterDlg : public QDialog
{
    Q_OBJECT
public:
    RegisterDlg(QWidget *parent = 0);
    ~RegisterDlg();
public slots:
    void checkRegister();
private:
    QVBoxLayout*  layout;
    QLabel*       label;
    QGridLayout*  gridlayout;
    QLabel*       namelabel;
    QLineEdit*    nameedit;
    QLabel*       codelabel;
    QLineEdit*    codeedit;
    QHBoxLayout*  hlayout;
    QPushButton*  confirm;
    QPushButton*  cancel;
};

#endif
//! ccsdu2004

cxx

#include <QtGui/QMessageBox>
#include "registerdlg.h"

RegisterDlg::RegisterDlg(QWidget *parent)
    : QDialog(parent)
{
    layout = new QVBoxLayout;
    label  = new QLabel(tr("Please input register info below"));
    layout->addWidget(label);
    gridlayout = new QGridLayout;
    namelabel  = new QLabel(tr("User Name"));
    nameedit   = new QLineEdit();
    codelabel  = new QLabel(tr("Register Code"));
    codeedit   = new QLineEdit();
    gridlayout->addWidget(namelabel,0,0);
    gridlayout->addWidget(nameedit,0,1);
    gridlayout->addWidget(codelabel,1,0);
    gridlayout->addWidget(codeedit,1,1);
    layout->addLayout(gridlayout);
    hlayout = new QHBoxLayout;
    confirm = new QPushButton(tr("Confirm"));
    cancel  = new QPushButton(tr("Cancel"));
    hlayout->addWidget(confirm);
    hlayout->addWidget(cancel);
    layout->addLayout(hlayout);
    this->setLayout(layout);
    this->setWindowTitle(tr("Register"));

connect(this->cancel,SIGNAL(clicked()),this,SLOT(close()));
    connect(this->confirm,SIGNAL(clicked()),this,SLOT(checkRegister()));
}

RegisterDlg::~RegisterDlg()
{
}

void RegisterDlg::checkRegister()
{
}

QT学习笔记-15.窗体切分

#include <QtGui/QApplication>
#include <QtGui/QTextEdit>
#include <QtGui/QSplitter>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

QTextEdit* text1 = NULL;
    QTextEdit* text2 = NULL;
    QSplitter* splitter;
    text1 = new QTextEdit;
    text2 = new QTextEdit;
    splitter = new QSplitter(Qt::Vertical);
    splitter->addWidget(text1);
    QTextEdit* text3 = new QTextEdit;
    QSplitter* sp1 = new QSplitter(Qt::Horizontal);
    splitter->addWidget(text2);
    splitter->setStretchFactor(1,1);
    sp1->addWidget(splitter);
    sp1->addWidget(text3);
    sp1->show();
    return a.exec();
}

QT学习笔记-16.Dock控件

一个简单的使用例子如下:

#include "mainwindow.h"
#include <QtGui/QDockWidget>
#include <QtGui/QTextEdit>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QDockWidget* widget = new QDockWidget(tr("DockWidget"));
    QTextEdit* edit = new QTextEdit;
    widget->setWidget(edit);
    widget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
    this->addDockWidget(Qt::LeftDockWidgetArea,widget);
}

MainWindow::~MainWindow()
{

}

需要说明的是仅MainWidow仅可设置Dock

QT学习笔记-17. QT拖放

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    edit = new QTextEdit;
    this->setCentralWidget(edit);
    setAcceptDrops(true);
    this->setWindowTitle(tr("Text Editor"));
}

MainWindow::~MainWindow()
{
}

void MainWindow::dragEnterEvent(QDragEnterEvent* event)
{
    if(event->mimeData()->hasFormat("text/uri-list"))
        event->acceptProposedAction();
}

void MainWindow::dropEvent(QDropEvent* event)
{
    QList<QUrl> uri = event->mimeData()->urls();
    if(uri.isEmpty())
        return;
    QString file = uri.first().toLocalFile();
    if(file.isEmpty())
        return;
    this->setWindowTitle(tr("%1 -- %2").arg(file).arg("Drag File"));
}

QT学习笔记-18 IconEditor

#include <QColor>
#include <QImage>
#include <QtGui/QWidget>

class Widget : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(QColor penColor READ penColor WRITE setPenColor)
    Q_PROPERTY(QImage iconImage READ iconImage WRITE setIconImage)
    Q_PROPERTY(int zoomFactor READ zoomFactor WRITE setZoomFactor)
public:
    Widget(QWidget *parent = 0);
    ~Widget();

void   setPenColor(const QColor& newColor);
    QColor penColor()const{return curColor;}
    void   setZoomFactor(int newZoom);
    int    zoomFactor()const{return zoom;}
    void   setIconImage(const QImage& image);
    QImage iconImage()const{return image;}
    QSize  sizeHint()const;
protected:
    void   mousePressEvent(QMouseEvent *event);
    void   mouseMoveEvent(QMouseEvent* event);
    void   paintEvent(QPaintEvent* event);
private:
    void   setImagePixel(const QPoint &pos,bool opaque);
    QRect  pixelRect(int i,int j)const;

QColor curColor;
    QImage image;
    int    zoom;
};

#include <QtGui>

#include "widget.h"

Widget::Widget(QWidget *parent)

: QWidget(parent)

{

this->setAttribute(Qt::WA_StaticContents);

this->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);

this->curColor = Qt::black;

this->zoom = 8;

image = QImage(16,16,QImage::Format_ARGB32);

image.fill(qRgba(0,0,0,0));

}

Widget::~Widget()

{

}

QSize Widget::sizeHint()const

{

QSize size = zoom * image.size();

if(zoom >= 3)

size += QSize(1,1);

return size;

}

void Widget::setPenColor(const QColor& newColor)

{

curColor = newColor;

}

void Widget::setIconImage(const QImage& image)

{

if(this->image != image)

{

this->image = image.convertToFormat(QImage::Format_ARGB32);

update();

this->updateGeometry();

}

}

void Widget::paintEvent(QPaintEvent* event)

{

QPainter painter(this);

if(zoom >=3)

{

painter.setPen(this->palette().foreground().color());

for(int i = 0; i <= image.width();++i)

painter.drawLine(zoom*i,0,zoom*i,zoom*image.height());

for(int j = 0;j <= image.height();j++)

painter.drawLine(0,zoom*j,zoom*image.width(),zoom*j);

}

for(int i = 0; i < image.width();i++)

{

for(int j = 0;j < image.height();j++)

{

QRect rect = this->pixelRect(i,j);

if(!event->region().intersect(rect).isEmpty())

{

QColor color = QColor::fromRgba(image.pixel(i,j));

if(color.alpha() < 255)

painter.fillRect(rect,Qt::white);

painter.fillRect(rect,color);

}

}

}

}

QRect Widget::pixelRect(int i, int j) const

{

if(zoom >=3)

return QRect(zoom*i+1,zoom*j+1,zoom-1,zoom-1);

return QRect(zoom*i,zoom*j,zoom,zoom);

}

void Widget::mousePressEvent(QMouseEvent *event)

{

if(event->button() == Qt::LeftButton)

setImagePixel(event->pos(),true);

else if(event->button() == Qt::RightButton)

setImagePixel(event->pos(),false);

}

void Widget::mouseMoveEvent(QMouseEvent *event)

{

if(event->buttons() & Qt::LeftButton)

setImagePixel(event->pos(),true);

else if(event->buttons() & Qt::RightButton)

setImagePixel(event->pos(),false);

}

void Widget::setImagePixel(const QPoint &pos, bool opaque)

{

int i = pos.x()/zoom;

int j = pos.y()/zoom;

if(image.rect().contains(i,j))

{

if(opaque)

image.setPixel(i,j,penColor().rgba());

else

image.setPixel(i,j,qRgba(0,0,0,0));

this->update(this->pixelRect(i,j));

}

}

void Widget::setZoomFactor(int newZoom)

{

if(newZoom < 1)

newZoom = 1;

if(newZoom != zoom)

{

zoom = newZoom;

update();

updateGeometry();

}

}

几点说明:
1.宏 Q_PROPERTY 声明属性读写属性
2.setSizePolicy(.,.) 说明控件最小尺寸为推荐尺寸
3.sizeHint() 获得控件推荐尺寸
4.控件 update()/updateGeometry()用于下次重绘和调整控件尺寸
5.在函数paintEvent中绘制图元
6.一个控件的调色板有3个颜色组 激活,非激活,不可用

QT学习笔记-19 ScroolArea

#include <QtGui/QApplication>
#include <QtGui/QScrollArea>
#include "widget.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget *widget = new Widget;

QScrollArea area;
    area.setWidget(widget);
    area.viewport()->setBackgroundRole(QPalette::Dark);
    area.viewport()->setAutoFillBackground(true);
    area.setWindowTitle("Icon Cool");
    area.show();

return a.exec();
}

QT学习笔记-20.使用QT Designer开发UI

使用QT Designer设计软件界面
使用过程没什么说的

假定生成的ui文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget class="QWidget" name="Form">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>203</width>
    <height>177</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <widget class="QWidget" name="">
   <property name="geometry">
    <rect>
     <x>20</x>
     <y>20</y>
     <width>164</width>
     <height>139</height>
    </rect>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout_3">
    <item>
     <widget class="QLineEdit" name="lineEdit"/>
    </item>
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
       <layout class="QVBoxLayout" name="verticalLayout_2">
        <item>
         <widget class="QPushButton" name="pushButton_7">
          <property name="text">
           <string>PushButton</string>
          </property>
         </widget>
        </item>
        <item>
         <widget class="QPushButton" name="pushButton_5">
          <property name="text">
           <string>PushButton</string>
          </property>
         </widget>
        </item>
        <item>
         <widget class="QPushButton" name="pushButton">
          <property name="text">
           <string>PushButton</string>
          </property>
         </widget>
        </item>
       </layout>
      </item>
      <item>
       <layout class="QVBoxLayout" name="verticalLayout">
        <item>
         <widget class="QPushButton" name="pushButton_2">
          <property name="text">
           <string>PushButton</string>
          </property>
         </widget>
        </item>
        <item>
         <widget class="QPushButton" name="pushButton_8">
          <property name="text">
           <string>PushButton</string>
          </property>
         </widget>
        </item>
        <item>
         <widget class="QPushButton" name="pushButton_4">
          <property name="text">
           <string>PushButton</string>
          </property>
         </widget>
        </item>
       </layout>
      </item>
     </layout>
    </item>
   </layout>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

然后修改pro文件
加入对QUitools的链接

CONFIG += uitools

其main.cpp如下:

#include <QFile>
#include <QtGui/QApplication>
#include <QtGui/QWidget>
#include <QtGui/QLineEdit>
#include <QtUiTools/QuiLoader>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QUiLoader ui;
    QFile file("dlg.ui");
    QWidget* widget = ui.load(&file);
    if(widget)
    {
        widget->setWindowTitle("Dlg");
        QLineEdit* lineedit = widget->findChild<QLineEdit*>("lineEdit");
        lineedit->setStyleSheet("QLineEdit {background-color: yellow}");
        lineedit->setText("information.");
        widget->show();
    }
    return a.exec();
}

QT学习笔记-21.使用QT TabWidget

学习QTabWidget例子
1.

#ifndef GENERALTAB_H
#define GENERALTAB_H
#include <QWidget>
#include <QFileInfo>

class GeneralTab : public QWidget
{
    Q_OBJECT
public:
    GeneralTab(const QFileInfo &fileInfo, QWidget *parent = 0);
    ~GeneralTab();
};

#endif

源文件:

#include "generaltab.h"
#include <QDateTime>
#include <QtGui/QVBoxLayout>
#include <QtGui/QLabel>
#include <QtGui/QLineEdit>

GeneralTab::~GeneralTab(){}

GeneralTab::GeneralTab(const QFileInfo &fileInfo, QWidget *parent):
QWidget(parent)
{
     QLabel *fileNameLabel = new QLabel(tr("File Name:"));
     QLineEdit *fileNameEdit = new QLineEdit(fileInfo.fileName());
     QLabel *pathLabel = new QLabel(tr("Path:"));
     QLabel *pathValueLabel = new QLabel(fileInfo.absoluteFilePath());
     pathValueLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken);

QLabel *sizeLabel = new QLabel(tr("Size:"));
     qlonglong size = fileInfo.size()/1024;
     QLabel *sizeValueLabel = new QLabel(tr("%1 K").arg(size));
     sizeValueLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken);

QLabel *lastReadLabel = new QLabel(tr("Last Read:"));
     QLabel *lastReadValueLabel = new QLabel(fileInfo.lastRead().toString());
     lastReadValueLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken);

QLabel *lastModLabel = new QLabel(tr("Last Modified:"));
     QLabel *lastModValueLabel = new QLabel(fileInfo.lastModified().toString());
     lastModValueLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken);

QVBoxLayout *mainLayout = new QVBoxLayout;
     mainLayout->addWidget(fileNameLabel);
     mainLayout->addWidget(fileNameEdit);
     mainLayout->addWidget(pathLabel);
     mainLayout->addWidget(pathValueLabel);
     mainLayout->addWidget(sizeLabel);
     mainLayout->addWidget(sizeValueLabel);
     mainLayout->addWidget(lastReadLabel);
     mainLayout->addWidget(lastReadValueLabel);
     mainLayout->addWidget(lastModLabel);
     mainLayout->addWidget(lastModValueLabel);
     mainLayout->addStretch(1);

setLayout(mainLayout);
}

如上是QTabWidget中一个页面对象

#ifndef DIALOG_H
#define DIALOG_H

#include <QtGui/QDialog>
#include <QtGui/QTabWidget>
#include <QtGui/QDialogButtonBox>

class Dialog : public QDialog
{
    Q_OBJECT
public:
    Dialog(QWidget *parent = 0);
    ~Dialog();
private:
    QTabWidget       *tab;
    QDialogButtonBox *buttonbox;
};

#endif // DIALOG_H

#include "dialog.h"
#include <QFileInfo>
#include <QDialogButtonBox>
#include <QDateTime>
#include <QtGui/QVBoxLayout>
#include <QtGui/QLabel>
#include <QtGui/QLineEdit>
#include "generaltab.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    QFileInfo fileInfo("tab.exe");
    tab = new QTabWidget;
    tab->addTab(new GeneralTab(fileInfo),tr("Info1"));
    tab->addTab(new GeneralTab(fileInfo),tr("Info2"));
    tab->addTab(new GeneralTab(fileInfo),tr("Info3"));

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(tab);
    layout->addWidget(buttonbox);
    setLayout(layout);
    setWindowTitle(tr("Tab Dialog"));
}

Dialog::~Dialog()
{
}

QT学习笔记-22.使用QT TableView(1)

使用QT TableView
感觉QTableView还是蛮复杂的
QTableView是显示表格状的视图

其经常使用的函数有
1.显示格子 setShowGrid(false);
2.由内容调整列 resizeColumnsToContents();
3.获取垂直表头 verticalHeader
();
         当然还有水平表头
4.设置非编辑状态

verticalView->setEditTriggers(QTableView::NoEditTriggers);

5.设置点击行为

verticalView->setSelectionBehavior(QTableView::SelectRows);
6.模型对象

QStandardItemModel *model = new QStandardItemModel;

model->setColumnCount(4);

model->setHeaderData(0,Qt::Horizontal,tr("File"));

model->setHeaderData(1,Qt::Horizontal,tr("Path"));

model->setHeaderData(2,Qt::Horizontal,tr("Size"));

model->setHeaderData(3,Qt::Horizontal,tr("Duration"));

设置显示模型为4列
7.增加项到模型

QStandardItem* item1 = new QStandardItem(tr("Yesterday Once More.mid"));

QStandardItem* item2 = new QStandardItem(tr("C://Mid//"));

QStandardItem* item3 = new QStandardItem(tr("0.001M"));

QStandardItem* item4 = new QStandardItem(tr("3:48"));

QList<QStandardItem*> item;

item << item1 << item2 << item3 << item4;

model->appendRow(item);
8.设置模型到View

setModel(model);

QT学习笔记-23.Qt获取Md5值

1.

#include <QtCore/QCoreApplication>

#include <QCryptographicHash>

#include <iostream>

int main(int argc, char *argv[])

{

QCoreApplication a(argc, argv);

QString pwd="abcdef";

QString md5;

QByteArray ba,bb;

QCryptographicHash md(QCryptographicHash::Md5);

ba.append(pwd);

md.addData(ba);

bb = md.result();

md5.append(bb.toHex());

std::cout<<md5.toStdString()<<std::endl;

return a.exec();

}

2.

#include <QtCore/QCoreApplication>

#include <QCryptographicHash>

#include <iostream>

int main(int argc, char *argv[])

{

QCoreApplication a(argc, argv);

QString md5;

QString pwd="abcdef";

QByteArray bb;

bb = QCryptographicHash::hash(pwd.toAscii(),QCryptographicHash::Md5 );

md5.append(bb.toHex());

std::cout<<md5.toStdString()<<std::endl;

return a.exec();

}

QT学习笔记-24.使用QTimeLine

一个简单的代码如下:

#include <QtGui/QApplication>

#include <QtGui>

#include <math.h>

int main(int argc, char *argv[])

{

QApplication a(argc, argv);

QGraphicsItem *ball = new QGraphicsEllipseItem(0,0,20,40);

QTimeLine *timer = new QTimeLine(15000);

timer->setFrameRange(0,100);

QGraphicsItemAnimation *animation = new QGraphicsItemAnimation;

animation->setItem(ball);

animation->setTimeLine(timer);

for(int i = 0; i < 600; ++i)

animation->setPosAt(i / 600.0, QPointF(i, i));

QGraphicsScene *scene = new QGraphicsScene();

scene->setBackgroundBrush(QBrush(Qt::blue));

scene->setSceneRect(0,0,250,250);

scene->addItem(ball);

QGraphicsView *view = new QGraphicsView(scene);

view->setBackgroundBrush(QBrush(Qt::red));

view->show();

timer->start();

return a.exec();

}

另外一个例子如下:

#ifndef TIMELINE_H
#define TIMELINE_H
#include <QtGui/QWidget>
#include <QVBoxLayout>
#include <QTimeLine>
#include <QProgressBar>
#include <QPushButton>

class timeline : public QWidget
{
    Q_OBJECT
public:
    timeline(QWidget *parent = 0);
    ~timeline();
private:
    QPushButton *pushButton;
    QTimeLine *timeLine;
    QProgressBar *progressBar;
    QVBoxLayout *layout;
};

#endif // TIMELINE_H

#include "timeline.h"

timeline::timeline(QWidget *parent):QWidget(parent)
{
    layout= new QVBoxLayout(this);
    progressBar = new QProgressBar(this);
    progressBar->setRange(0, 100);

// Construct a 5-second timeline with a frame range of 0 - 100
    timeLine = new QTimeLine(5000, this);
    timeLine->setFrameRange(0, 100);
    connect(timeLine, SIGNAL(frameChanged(int)), progressBar, SLOT(setValue(int)));

// Clicking the push button will start the progress bar animation
    pushButton = new QPushButton(tr("Start animation"), this);
    connect(pushButton, SIGNAL(clicked()), timeLine, SLOT(start()));
    layout->addWidget(progressBar);
    layout->addWidget(pushButton);
    setLayout(layout);
}

timeline::~timeline()
{
   // No need to delete any QObject that got proper parent pointer.
}

简单的说 QTimeLine就是一个带有线程的对象,通过设置持续时间和帧数来控制动画

QT学习笔记-25.QProgressBar和QThread

基本上所有的GUI都不允许在线程中操作GUI
QT也是一样

那么在QT中如何操作呢?
举一个例子具体如下:

GUI中

connect(thread,SIGNAL(notify(int)),this,SLOT(updateProgress(int)));

void MainWindow::updateProgress(int value)

{

progressbar->setValue(value);

}

Thread中

signals:

void notify(int);

Thread run中

emit notify(percent);

很犀利吧

QT学习笔记-26.QT文件读写

1.写二进制文件

#include <QtCore/QCoreApplication>

#include <QFile>

#include <QDataStream>

#include <iostream>

int main(int argc, char *argv[])

{

QCoreApplication a(argc, argv);

QFile file("file.dat");

if(!file.open(QIODevice::WriteOnly))

{

std::cerr<<qPrintable(file.errorString())<<std::endl;

return -1;

}

QDataStream stream(&file);

stream.setVersion(9);

QString id("ID:");

quint32 num(quint32(0x123456));

stream << id<< num;

file.close();

return a.exec();

}

2.类似读文件则是:

#include <QtCore/QCoreApplication>

#include <QFile>

#include <QDataStream>

#include <iostream>

int main(int argc, char *argv[])

{

QCoreApplication a(argc, argv);

QFile file("file.dat");

if(!file.open(QIODevice::ReadOnly))

{

std::cerr<<qPrintable(file.errorString())<<std::endl;

return -1;

}

QDataStream stream(&file);

stream.setVersion(9);

QString id;

quint32 num;

stream >> id >> num;

std::cout<<id.toStdString()<<" "<<num<<std::endl;

file.close();

return a.exec();

}

感觉比较好的是直接可以读写字符串而不需要关心字符串长度 这个比较好

3.写文本文件

#include <QtCore/QCoreApplication>

#include <QFile>

#include <QTextStream>

#include <iostream>

int main(int argc, char *argv[])

{

QCoreApplication a(argc, argv);

QFile file("output.txt");

if(!file.open(QIODevice::WriteOnly))

{

std::cerr<<qPrintable(file.errorString())<<std::endl;

return -1;

}

QTextStream stream(&file);

QString id("Eric Home.");

quint32 num(123456);

stream << id << num;

file.close();

return a.exec();

}

4.读文本文件
则可以通过设置编码方式 之后一次性读入或者以一个字符的模式读入

QT学习笔记-26.QT XML读写

1、读操作:

QDomDocument doc( “mydocument " );

QFile file( "ccc.xml" );

if ( !file.open( IO_ReadOnly ) )

{

return;

}

if ( !doc.setContent( &file ) )

{

file.close();

return;

}

file.close();

2、写操作

原理很简单,由于XML是分级结构,因此只要找到需要写的Node的所在的级别,然后调用setNodeValue("value")就写好了。

<?xml version="1.0" encoding="unicode" ?>

<XML>

第一级:<MAINT TableName="RSBT_STATION" OtherInfo="" opttype="1" version="1.0.0" FormTableName="TABLE11">

第二级:<FORM opttype="1">

第三级:<STDI>0001(第四级)</STDI>

<GUID /> (第四级)

<TAPPCODE>111111111111(第四级)</TAPPCODE>

在上边的代码中,如果是想改变111111111111的值,由于它处在第四级,因此只要

QDomElement docElem = doc.documentElement();

QDomNode node = docElem.childNodes().item(0).childNodes().item(0).childNodes().item(0);

那么node对象就是指的111111111111了。

3、保存

方法就更简单了,如果是调用save函数,可能会报错,至少我用save函数就没能实现保存;这里有一个非常简单的法:就是

QString xml = doc.toString();

也就是说将QDomDocument对象变成字符串,已经成字符串了,应该知道怎么保存了吧。

QT学习笔记-27.一段涉及多线程的读写缓冲对象(QT)

源于lmms
代码如下:

#include <QtCore/QSemaphore>

template<typename T>
class fifoBuffer
{
public:
    fifoBuffer( int _size ) :
        m_reader_sem( _size ),
        m_writer_sem( _size ),
        m_reader_index( 0 ),
        m_writer_index( 0 ),
        m_size( _size )
    {
        m_buffer = new T[_size];
        m_reader_sem.acquire( _size );
    }

~fifoBuffer()
    {
        delete[] m_buffer;
        m_reader_sem.release( m_size );
    }

void write( T _element )
    {
        m_writer_sem.acquire();
        m_buffer[m_writer_index++] = _element;
        m_writer_index %= m_size;
        m_reader_sem.release();
    }

T read()
    {
        m_reader_sem.acquire();
        T element = m_buffer[m_reader_index++];
        m_reader_index %= m_size;
        m_writer_sem.release();
        return( element );
    }

bool available()
    {
        return( m_reader_sem.available() );
    }

private:
    QSemaphore m_reader_sem;
    QSemaphore m_writer_sem;
    int m_reader_index;
    int m_writer_index;
    int m_size;
    T * m_buffer;

} ;

QT学习笔记-28.QT插件

就不费话了,直接点
来一个我做的插件例子

//! 插件基类

class PluginAddon : public QObject

{

Q_OBJECT

public:

PluginAddon

(){}

virtual ~

PluginAddon

(){}

public:

...

signals:

void notify(const Target& t);

};

Q_DECLARE_INTERFACE(

PluginAddon

,"ooo/1.0.0")

具体插件

class cPluginon : public PluginAddon

{

Q_OBJECT

// 将该接口注册到Qt的meta-object system

Q_INTERFACES(PluginAddon)

public:

...

};

.cpp

Q_EXPORT_PLUGIN2(cplug_Plugin,cPluginon)

这个宏所在头文件是:

#include <QtPlugin>

至于插件的使用.

loader = new QPluginLoader("dongrays_Plugin.dll");

QObject* instance = loader->instance();

if(instance)

{

interface = qobject_cast<Addon*>(instance);

connect(interface,SIGNAL(notify(target)),this,SLOT(getInfo(target)));

}

谈过connect照样可以再插件之前传送数据

QT学习笔记-29.使用QT HTTP下载网络文件

QT附带的例子比较好:

class HttpWindow : public QDialog
{
    Q_OBJECT
public:
    HttpWindow(QWidget *parent = 0);

void startRequest(QUrl url);
private slots:
    void downloadFile();
    void cancelDownload();
    void httpFinished();
    void httpReadyRead();
    void updateDataReadProgress(qint64 bytesRead, qint64 totalBytes);
    void enableDownloadButton();
    void slotAuthenticationRequired(QNetworkReply*,QAuthenticator *);
private:
    QLabel *statusLabel;
    QLabel *urlLabel;
    QLineEdit *urlLineEdit;
    QProgressDialog *progressDialog;
    QPushButton *downloadButton;
    QPushButton *quitButton;
    QDialogButtonBox *buttonBox;

QUrl url;
    QNetworkAccessManager qnam;
    QNetworkReply *reply;
    QFile *file;
    int httpGetId;
    bool httpRequestAborted;
};

其中槽有:
1.开始下载
2.取消下载
3.预备下载
4.下载完成
5.进度回调

实现为:

void HttpWindow::startRequest(QUrl url)
{
    reply = qnam.get(QNetworkRequest(url));
    connect(reply, SIGNAL(finished()),
            this, SLOT(httpFinished()));
    connect(reply, SIGNAL(readyRead()),
            this, SLOT(httpReadyRead()));
    connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
            this, SLOT(updateDataReadProgress(qint64,qint64)));
}

该函数主要针对给定url绑定事件

void HttpWindow::downloadFile()
{
    url = urlLineEdit->text();

QFileInfo fileInfo(url.path());
    QString fileName = fileInfo.fileName();
    fileName = "downloadfile.dat";
    if(fileName.isEmpty())
        fileName = "index.html";

if(QFile::exists(fileName)) {
        if (QMessageBox::question(this, tr("HTTP"), 
                                  tr("There already exists a file called %1 in "
                                     "the current directory. Overwrite?").arg(fileName),
                                  QMessageBox::Yes|QMessageBox::No, QMessageBox::No)
            == QMessageBox::No)
            return;
        QFile::remove(fileName);
    }

file = new QFile(fileName);
    if (!file->open(QIODevice::WriteOnly)) {
        QMessageBox::information(this, tr("HTTP"),
                                 tr("Unable to save the file %1: %2.")
                                 .arg(fileName).arg(file->errorString()));
        delete file;
        file = 0;
        return;
    }

progressDialog->setWindowTitle(tr("HTTP"));
    progressDialog->setLabelText(tr("Downloading %1.").arg(fileName));
    downloadButton->setEnabled(false);

// schedule the request
    httpRequestAborted = false;
    startRequest(url);
}

当点击下载的时候,会执行该函数
获取url链接,生成本地文件,...

void HttpWindow::cancelDownload()
{
    statusLabel->setText(tr("Download canceled."));
    httpRequestAborted = true;
    reply->abort();
    downloadButton->setEnabled(true);
}

终止下载,主要函数是reply->abort();

void HttpWindow::httpFinished()
{
    if (httpRequestAborted) {
        if (file) {
            file->close();
            file->remove();
            delete file;
            file = 0;
        }
        reply->deleteLater();
        progressDialog->hide();
        return;
    }

progressDialog->hide();
    file->flush();
    file->close();

QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
    if (reply->error()) {
        file->remove();
        QMessageBox::information(this, tr("HTTP"),
                                 tr("Download failed: %1.")
                                 .arg(reply->errorString()));
        downloadButton->setEnabled(true);
    } else if (!redirectionTarget.isNull()) {        
        QUrl newUrl = url.resolved(redirectionTarget.toUrl());
        if (QMessageBox::question(this, tr("HTTP"),
                                  tr("Redirect to %1 ?").arg(newUrl.toString()),
                                  QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
            url = newUrl;
            reply->deleteLater();
            file->open(QIODevice::WriteOnly);
            file->resize(0);
            startRequest(url);
            return;
        }
    } else {
        QString fileName = QFileInfo(QUrl(urlLineEdit->text()).path()).fileName();
        statusLabel->setText(tr("Downloaded %1 to current directory.").arg(fileName));
        downloadButton->setEnabled(true);
    }

reply->deleteLater();
    reply = 0;
    delete file;
    file = 0;
}

下载结束动作

void HttpWindow::httpReadyRead()
{
    // this slot gets called every time the QNetworkReply has new data.
    // We read all of its new data and write it into the file.
    // That way we use less RAM than when reading it at the finished()
    // signal of the QNetworkReply
    if (file)
        file->write(reply->readAll());
}

写文件回调

void HttpWindow::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes)
{
    if (httpRequestAborted)
        return;

progressDialog->setMaximum(totalBytes);
    progressDialog->setValue(bytesRead);
}

进度回调

要点:
1.针对QNetReply绑定需要的信号和槽
2.实现需要的槽函数

QT学习笔记-30.自写的QT插件系统

#ifndef QPLUGIN_SYSTEM_H
#define QPLUGIN_SYSTEM_H
#include <QObject>
#include <QVector>
#include <QPluginLoader>
#include <QDir>

template<class T>
class QPluginSystem
{
public:
    void setup();
    int  getAddonCnt(){return addons.size();}
    T*   getAddonByIndex(int index){return addons.at(index);}    
private:
    QVector<QPluginLoader*> loaders;
    QVector<T*>             addons;
};

template<class T>
void QPluginSystem<T>::setup()
{
    QString path = QDir::currentPath();
    path += QDir::separator();
    path += "addons";
    QDir pluginsDir(path);

foreach(QString fileName,pluginsDir.entryList(QDir::Files))
    {   
        bool autodel = false;
        QPluginLoader* pluginLoader = new QPluginLoader(pluginsDir.absoluteFilePath(fileName));
        QObject *plugin = pluginLoader->instance();
        if(plugin)
        {
            T *interface = qobject_cast<T*>(plugin);
            if(interface)
            {
                addons.push_back(interface);
                loaders.push_back(pluginLoader);
                autodel = true;
            }
        }

if(autodel == false)
            delete pluginLoader;
    }
}

#endif
其中T是插件对象,需要继承QObject
另外虽然我没试过,但是我感觉增加QPluginLoader链表是很有必要的

QT学习笔记-30.QTableView只显示横格的方式

默认QTableView是显示网状格子的,如果不显示网格则可以调用setShowGrid(false);来实现。但是如果只想显示横线则有点复杂了。具体代码如下:

#include <QApplication>

#include <QTableWidget>

#include <QPainter>

#include <QStyledItemDelegate>

#include <QHeaderView>

class QLineDelegate : public QStyledItemDelegate

{

public:

QLineDelegate(QTableView* tableView);

protected:

void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;

private:

QPen pen;

QTableView* view;

};

QLineDelegate::QLineDelegate(QTableView* tableView)

{

int gridHint = tableView->style()->styleHint(QStyle::SH_Table_GridLineColor, new QStyleOptionViewItemV4());

QColor gridColor = static_cast<QRgb>(gridHint);

pen = QPen(gridColor, 0, tableView->gridStyle());

view = tableView;

}

void QLineDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,const QModelIndex& index)const

{

QStyledItemDelegate::paint(painter, option, index);

QPen oldPen = painter->pen();

painter->setPen(pen);

//painter->drawLine(option.rect.topRight(), option.rect.bottomRight());

painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight());

painter->setPen(oldPen);

}

class QLineTableWidget:public QTableWidget

{

public:

QLineTableWidget();

};

QLineTableWidget::QLineTableWidget()

{

setStyleSheet("QTableView::Item{selection-background-color:#101020}");

setStyleSheet("QTableView::Item{background-color:#F0F0F0}");

verticalHeader()->setVisible(false);

horizontalHeader()->setVisible(true);

setSelectionBehavior(QAbstractItemView::SelectRows);

setSelectionMode(QAbstractItemView::SingleSelection);

setEditTriggers(QTableView::NoEditTriggers);

setColumnCount(3);

setRowCount(4);

setShowGrid(false);

setItemDelegate(new QLineDelegate(this));

setCurrentCell(-1,-1);

}

int main(int argc,char **argv)

{

QApplication a(argc,argv);

QLineTableWidget widget;

widget.show();

return a.exec();

}

QT学习笔记-31.QTableView只显示横格,不显示点击虚框的方法

重新风格项代理QStyledItemDelegat

class QLineDelegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    QLineDelegate(QTableView* tableView);
protected:
    void paint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index) const;
private:
    QPen         pen;
    QTableView*  view;
};

#include <QPainter>
#include "QLineDelegate.h"

QLineDelegate::QLineDelegate(QTableView* tableView)
{
    int gridHint = tableView->style()->styleHint(QStyle::SH_Table_GridLineColor, new QStyleOptionViewItemV4());
    QColor gridColor = static_cast<QRgb>(gridHint);
    pen = QPen(gridColor, 0, tableView->gridStyle());
    view = tableView;
}

void QLineDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,const QModelIndex& index)const
{
    QStyleOptionViewItem itemOption(option);
    if(itemOption.state & QStyle::State_HasFocus)
        itemOption.state = itemOption.state ^ QStyle::State_HasFocus;
    QStyledItemDelegate::paint(painter,itemOption,index);
    QPen oldPen = painter->pen();
    painter->setPen(pen);
    //painter->drawLine(option.rect.topRight(),option.rect.bottomRight());
    painter->drawLine(itemOption.rect.bottomLeft(),itemOption.rect.bottomRight());
    painter->setPen(oldPen);
}

QT学习笔记-32.QTableWidget增加QCheckBox的方法

#include <QtGui>

class ItemDelegate : public QItemDelegate
{
public:
    ItemDelegate(QObject *parent = 0)
        : QItemDelegate(parent)
    {
    }
    virtual void drawCheck(QPainter *painter, const QStyleOptionViewItem &option,
        const QRect &, Qt::CheckState state)const
    {
        const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;

QRect checkRect = QStyle::alignedRect(option.direction, Qt::AlignCenter,
            check(option, option.rect, Qt::Checked).size(),
            QRect(option.rect.x() + textMargin, option.rect.y(),
            option.rect.width() - (textMargin * 2), option.rect.height()));
        QItemDelegate::drawCheck(painter, option, checkRect, state);
    }
    virtual bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option,
        const QModelIndex &index)
    {
        Q_ASSERT(event);
        Q_ASSERT(model);

Qt::ItemFlags flags = model->flags(index);
        if(!(flags & Qt::ItemIsUserCheckable) || !(flags & Qt::ItemIsEnabled))
            return false;

QVariant value = index.data(Qt::CheckStateRole);
        if(!value.isValid())
            return false;

if(event->type() == QEvent::MouseButtonRelease)
        {
            const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
            QRect checkRect = QStyle::alignedRect(option.direction, Qt::AlignCenter,
                check(option, option.rect, Qt::Checked).size(),
                QRect(option.rect.x() + textMargin, option.rect.y(),
                option.rect.width() - (2 * textMargin), option.rect.height()));
            if (!checkRect.contains(static_cast<QMouseEvent*>(event)->pos()))
                return false;
        }
        else if(event->type() == QEvent::KeyPress)
        {
            if(static_cast<QKeyEvent*>(event)->key() != Qt::Key_Space
                && static_cast<QKeyEvent*>(event)->key() != Qt::Key_Select)
                return false;
        }
        else
        {
            return false;
        }
        Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked
            ? Qt::Unchecked : Qt::Checked);

//!

return model->setData(index, state, Qt::CheckStateRole);
    }
    void drawFocus(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect) const
    {
        QItemDelegate::drawFocus(painter, option, option.rect);
    }
};

static int ROWS = 3;
static int COLS = 3;

class Table : public QTableWidget
{
public:
    Table(QWidget *parent = 0)
        : QTableWidget(ROWS, COLS, parent)
    {
        setItemDelegate(new ItemDelegate(this));
        QTableWidgetItem *item = 0;
        for(int i=0; i<rowCount(); ++i)
        {
            for(int j=0; j<columnCount(); ++j)
            {
                setItem(i, j, item = new QTableWidgetItem);
                QTableViewItem;
                item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsUserCheckable);
                item->setCheckState((i+j) % 2 == 0 ? Qt::Checked : Qt::Unchecked);
            }
        }
    }
};

int main(int argc, char **argv)
{
    QApplication a(argc, argv);
    Table w;
    w.show();
    return a.exec();
}

QT学习笔记-33.QTableView增加QCheckBox的方法

使用Delegate具体如下:

class QLineDelegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    QLineDelegate(QTableView* tableView);
protected:
    void paint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index) const;
    bool editorEvent(QEvent *event,
                                         QAbstractItemModel *model,
                                         const QStyleOptionViewItem &option,
                                         const QModelIndex &index) ;
private:
    QPen         pen;
    QTableView*  view;
};

static QRect CheckBoxRect(const QStyleOptionViewItem &view_item_style_options)
{
    QStyleOptionButton check_box_style_option;
    QRect check_box_rect = QApplication::style()->subElementRect(
        QStyle::SE_CheckBoxIndicator,
        &check_box_style_option);

QPoint check_box_point(view_item_style_options.rect.x() +
                           view_item_style_options.rect.width() / 2 -
                           check_box_rect.width() / 2,
                           view_item_style_options.rect.y() +
                           view_item_style_options.rect.height() / 2 -
                           check_box_rect.height() / 2);
    return QRect(check_box_point, check_box_rect.size());
}

QLineDelegate::QLineDelegate(QTableView* tableView)
{
    int gridHint = tableView->style()->styleHint(QStyle::SH_Table_GridLineColor, new QStyleOptionViewItemV4());
    QColor gridColor = static_cast<QRgb>(gridHint);
    pen = QPen(gridColor,0,tableView->gridStyle());
    view = tableView;
}

void QLineDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,const QModelIndex& index)const
{
    bool checked = index.model()->data(index, Qt::DisplayRole).toBool();

if(index.column() == 0)
    {
        QStyleOptionButton check_box_style_option;
        check_box_style_option.state |= QStyle::State_Enabled;
        if(checked)
        {
            check_box_style_option.state |= QStyle::State_On;
        }
        else
        {
            check_box_style_option.state |= QStyle::State_Off;
        }
        check_box_style_option.rect = CheckBoxRect(option);
        QApplication::style()->drawControl(QStyle::CE_CheckBox,&check_box_style_option,painter);
    }

QStyledItemDelegate::paint(painter,option,index);
    QStyleOptionViewItem itemOption(option);
    if(itemOption.state & QStyle::State_HasFocus)
        itemOption.state = itemOption.state ^ QStyle::State_HasFocus;
    QStyledItemDelegate::paint(painter,itemOption,index);
    QPen oldPen = painter->pen();
    painter->setPen(pen);
    painter->drawLine(option.rect.topRight(),option.rect.bottomRight());
    painter->drawLine(itemOption.rect.bottomLeft(),itemOption.rect.bottomRight());
    painter->setPen(oldPen);
}

bool QLineDelegate::editorEvent(QEvent *event,
                                   QAbstractItemModel *model,
                                   const QStyleOptionViewItem &option,
                                   const QModelIndex &index) {
    if((event->type() == QEvent::MouseButtonRelease) ||
        (event->type() == QEvent::MouseButtonDblClick))
    {
        QMouseEvent *mouse_event = static_cast<QMouseEvent*>(event);
        if(mouse_event->button() != Qt::LeftButton ||
           !CheckBoxRect(option).contains(mouse_event->pos()))
        {
            return false;
        }

if(event->type() == QEvent::MouseButtonDblClick)
        {
            return true;
        }
    }
    else if(event->type() == QEvent::KeyPress)
    {
        if(static_cast<QKeyEvent*>(event)->key() != Qt::Key_Space &&
           static_cast<QKeyEvent*>(event)->key() != Qt::Key_Select)
        {
            return false;
        }
    }
    else
    {
        return false;
    }

bool checked = index.model()->data(index, Qt::DisplayRole).toBool();
    return model->setData(index, !checked, Qt::EditRole);
}

不过有一个小问题,就是CheckBox旁边有false/true字符

QT学习笔记-34.QT中Pro文件的写法

QT中 .pro文件的写法如下:

1. 注释
从“#”开始,到这一行结束。

2. 指定源文件
SOURCES = *.cpp

对于多源文件,可用空格分开,如:SOURCES = 1.cpp 2.cpp3.cpp
或者每一个文件可以被列在一个分开的行里面,通过反斜线另起一行,就像这样:

SOURCES = hello.cpp \
                  main.cpp
还有一种是这样

SOURCES+= hello.cpp
    SOURCES +=main.cpp

这种方法中使用“+=”比“=”更安全,因为它只是向已有的列表中添加新的文件,而不是替换整个列表。

3. 指定头文件
HEADERS = hello.h或者HEADERS += hello.h

列出源文件的任何一个方法对头文件也都适用。

4. 配置信息
CONFIG用来告诉qmake关于应用程序的配置信息。

CONFIG+= qt warn_on release

在这里使用“+=”,是因为我们添加我们的配置选项到任何一个已经存在中。这样做比使用“=”那样替换已经指定的所有选项是更安全的。
A> qt部分告诉qmake这个应用程序是使用Qt来连编的。这也就是说qmake在连接和为编译添加所需的包含路径的时候会考虑到Qt库的。
B> warn_on部分告诉qmake要把编译器设置为输出警告信息的。
C> release部分告诉qmake应用程序必须被连编为一个发布的应用程序。在开发过程中,程序员也可以使用debug来替换release

5. 指定目标文件名
TARGET = filename

如果不设置该项目,目标名会被自动设置为跟项目文件一样的名称

6. 添加界面文件(ui)
INTERFACES = filename.ui

7. 平台相关性处理
我们在这里需要做的是根据qmake所运行的平台来使用相应的作用域来进行处理。为Windows平台添加的依赖平台的文件的简单的作用域看起来就像这样:

win32 {
SOURCES += hello_win.cpp
}

所以如果qmake运行在Windows上的时候,它就会把hello_win.cpp添加到源文件列表中。如果qmake运行在其它平台上的时候,它会很简单地把这部分忽略。

8. 如果一个文件不存在,停止qmake
如 果某一个文件不存在的 时候,你也许不想生成一个Makefile。我们可以通过使用exists()函数来检查一个文件是否存在。我们可以通过使用error()函数把正在运 行的qmake停下来。这和作用域的工作方式一样。只要很简单地用这个函数来替换作用域条件。对main.cpp文件的检查就像这样:

!exists( main.cpp ) {
  error( "No main.cpp file found")
}

“!”用来否定这个测试,比如,如果文件存在,exists( main.cpp)是真,如果文件不存在,!exists( main.cpp )是真。

9. 检查多于一个的条件
假 设你使用Windows并且当你在命令 行运行你的应用程序的时候你想能够看到qDebug()语句。除非你在连编你的程序的时候使用console设置,你不会看到输出。我们可以很容易地把 console添加到CONFIG行中,这样在Windows下,Makefile就会有这个设置。但是如果告诉你我们只是想在当我们的应用程序运行在 Windows下并且当debug已经在CONFIG行中的时候,添加console。这需要两个嵌套的作用域;只要生成一个作用域,然后在它里面再生成 另一个。把设置放在最里面的作用域里,就像这样:

win32 {
  debug {
     CONFIG += console
  }
}

嵌套的作用域可以使用冒号连接起来,像这样:

win32:debug {
CONFIG += console
}

10. 摸板
模板变量告诉qmake为这个应用程序生成哪种makefile。下面是可供使用的选择:

A> app -建立一个应用程序的makefile。这是默认值,所以如果模板没有被指定,这个将被使用。
B> lib - 建立一个库的makefile。
C> vcapp - 建立一个应用程序的VisualStudio项目文件。
D> vclib - 建立一个库的VisualStudio项目文件。
E> subdirs -这是一个特殊的模板,它可以创建一个能够进入特定目录并且为一个项目文件生成makefile并且为它调用make的makefile。

11. 生成Makefile
当你已经创建好你的项目文件,生成Makefile就很容易了,你所要做的就是先到你所生成的项目文件那里然后输入:

Makefile可以像这样由“.pro”文件生成:

qmake -oMakefile hello.pro

对于VisualStudio的用户,qmake也可以生成“.dsp”文件,例如:

qmake -tvcapp -o hello.dsp hello.pro

QT学习笔记-35:QTableWidget动态增加行的方法

QTableWidget动态增加行的方法
其实很简单的:
首先rowCount()得到当前中的行数,然后在调用insertRow(row);即可
如果要动态增加列,方法类似

QT学习笔记-36.QTableWidget根据表格自动调整列宽度

QTableWidget要调整表格行宽主要涉及以下一个函数
1.resizeColumnsToContents();                      根据内容调整列宽           
2.resizeColumnToContents(int col);               根据内容自动调整给定列宽
3.horizontalHeader()->setResizeMode           把给定列设置为给定模式
主要模式有Stretch和Fixed

QT学习笔记-37.QRegex和正则表达式

QRegex提供字符串验证,匹配,搜索,替换和切割的功能
一个比较简单的例子是

QRegExp exp("-(.*)\(");
exp.setMinimal(true);

这儿匹配的是以-开头,以(结束的字符串
基本的QRegex
1.isValid()判断给定表达式是否合法
2.errorString()检错误和isValid()类似
3.isEmpty()判断正则表达式是否为空
4.caseSensitivity()检测大小写敏感
5.pattern()获取正则表达式本身
6.capturedTexts获取捕获的所有字符串
7.cap()获取捕获的字符串索引从1开始
8.numCaptures()返回匹配的字符串个数
9. indexIn ( const QString & str, int offset = 0, CaretMode caretMode= CaretAtZero ) const

从字符串给定偏移匹配之
10.还有一个函数需要交代的是setMinimal(int minimal)
该函数主要作用是开启或者关闭最小匹配
举一个例子:

"We must be <b>bold</b>, very <b>bold</b>!" and the pattern <b>.*</b>.

如果设置正则表达式为<b>.*</b>
如果设置为最大匹配,则捕获到<b>bold</b>,very <b>bold</b>
如果设置为正则表达式,
则第一次匹配到第一个<b>bold</b>
第二次匹配到第二个<b>bold</b>

基本的正则表达式如下:
\r       回车
\n      换行
\t      制表
\\      \本身
\"      "
\^    ^
\$    $
\s    匹配空白符
\~   匹配字符串开始
$     匹配字符串结束 
\b    单词的开始或者结束
[]    匹配其中的一个字符 比如[abc]匹配a,b或者c [^abc]匹配a,b,c之外的字符 [a-c] 匹配a到c之间的字符
{n} 匹配出现n次 比如ab{2} 相当于abb ab{1,3}相当于ab,abb,abbb
{n,}最少出现n次
?   出现0,1次 比如ab[cd]?相当于ab,abc,abd
++ 最少出现1次
*   不出现或者出现任意次,比如\^*c匹配 d,^d,^^d等

QT学习笔记-38.使用QSetting

QSetting类是QT中专门用于读写程序数据的对象
一个简单的使用例子如下:

QSettings setting("config.ini",QSettings::IniFormat);
    setting.beginGroup("config");
       setting.setValue("page",QVariant(3));
       setting.setValue("site",QVariant("http://www.cppblog.com/gaimor/"));
       setting.setValue("maker",QVariant("Gaimor"));
    setting.endGroup();

这个例子是把数据写到配置文件config.ini中去
当然也可以使用分组的方式写入,具体如下:

setting.setValue("config/page",QVariant(3));

setting.setValue("config/site",QVariant("http://www.cppblog.com/gaimor/"));

setting.setValue("config/maker",QVariant("Gaimor"));

它的读写值得函数原型如下:

void setValue(const QString &key, const QVariant &value);
    QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;

当然QSetting还有其他使用方式,以后慢慢总结

QT学习笔记(摘抄)相关推荐

  1. Qt学习笔记,Qt国际化

    Qt学习笔记,Qt国际化 Qt国际化步骤: 第一步:设置.pro文件,加入TRANSLATIONS为国际化做准备 TRANSLATIONS = language/language_en.ts\     ...

  2. Qt学习笔记,Qt程序架构设计要旨

    Qt学习笔记,Qt程序架构设计要旨 时间过得很快,转眼学习Qt已经有一个多月了,对Qt的学习也在不断的深入中.自己手下的code也很多了,不过不得不说,还有很多的部分没有接触过,比如网络编程,2D,3 ...

  3. Qt学习笔记之MySQL数据库

    一.MySQL概述 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQ ...

  4. Qt学习笔记之数据库

    一.数据库简介 1.1.数据和数据库(DB) 用计算机进行数据处理,首先就要把信息以数据形式存储到计算机中,故数据是可以被计算机接受和处理的符号.根据所表示的信息特征不同,数据有不同的类别,如数字.文 ...

  5. Qt学习笔记之文件处理

    Qt提供了通用的文件处理类QFile和处理文本的QTextStream类和处理二进制数据的QDataStream类,这些流操作极大地方便了对文件的督促存储.对文件信息和目录进行操作的类是QfileIn ...

  6. Qt学习笔记之国际化

    国际化的英文表述为Internationalization,通常简写为I18N(首尾字母加中间的字符数),一个应用程序的国际化就是使该应用程序可以让其他国家的用户使用的过程. 1. 相关的Qt类和AP ...

  7. Qt学习笔记之 字符串类型小结

    1. Qt常用字符串类型 1.1 QString QString是Unicode编码的字符串,存储一系列16位的QChar,每一个QChar对应一个Unicode 4.0编码的字符,详见<Qt学 ...

  8. Qt学习笔记,再次分析EVA源码之后得出的结论-QListView,QListViewItem(Qt3);Q3ListView,Q3ListViewItem(Qt4)...

    Qt学习笔记,再次分析EVA源码之后得出的结论-QListView,QListViewItem(Qt3);Q3ListView,Q3ListViewItem(Qt4) 今天再次分析了Eva的源码,也看 ...

  9. QT学习笔记(十六):setwindowflags的属性总结

    QT学习笔记(十六):setwindowflags的属性总结 此枚举类型用于为小部件指定各种窗口系统属性.它们是不常用的,但在一些情况下是必要的.其中一些标志取决于底层窗口管理器是否支持它们. 主要类 ...

最新文章

  1. UICollectionView的无限滚动---妥协做法
  2. 关于指针,可能是网上最详细的讲解了
  3. 半圆和圆锥在一起会产生什么神奇的反应?
  4. 华瑞网研(苏州)2014-11部分笔试题(社招)
  5. 项目: 基于Python socket模块实现的简单 ftp 项目:
  6. mysql 分区 range_Mysql分区|mysql分区表|mysql partition|by range
  7. mschart走势图 vc_VC++6.0中MsChart控件的用法
  8. 小波与小波包、小波包分解与信号重构、小波包能量特征提取 暨 小波包分解后实现按频率大小分布重新排列(Matlab 程序详解)
  9. 进程间通讯的7种方式
  10. 利用谷歌地图模拟地图坐标数据
  11. 【消费者心理与行为(第6版)】第7章 消费者的需要与购买动机
  12. 【转】一起做RGB-D SLAM (1)
  13. Python学习之字典练习(重复数字统计)
  14. idea批量重命名(快捷键+全部替换两种方式)
  15. 计算机网络学习笔记:基础知识
  16. 基于python+PHP+mysql的小区快递自助取件系统
  17. Ubuntu16.04开机左上角一条横杠以及局域网无法远程登录等问题
  18. 浅谈android studio中各个SdkVersion的含义
  19. 【知名的3D造型设计软件】犀牛 Rhinoceros 5.5.2 for Mac
  20. android加载h5速度慢的解决方案,WebView优化提高H5加载速度方案

热门文章

  1. 第十四课 斗地主项目课④ 游戏场景的ui
  2. [附源码]SSM计算机毕业设计车辆违章信息管理系统JAVA
  3. 做电影出品人的秘密,你知道多少!
  4. dw中flash透明参数
  5. 我与Apache DolphinScheduler的成长之路
  6. 法线向量(用于贴图)
  7. java利用poi实现Excel考勤报表的输出
  8. 目前最强性能的人脸检测算法(Wider Face Dataset)
  9. poi导出excel xls
  10. 前端七十二变之html和css入门