qt blog

目录

1. Qt5.4.0快捷方式 4css

2. 信号槽机制 4html

3. 窗口 5node

Qwidget,QDialog,QMainwindow的异同 6linux

3.1. 模式对话框 7c++

3.2. 非模式对话框 7git

3.3. 半模式对话框 7github

4. 基本元素 7算法

4.1. QLable: 7sql

4.2. QLineEdit 9数据库

4.3. QLCDNumbe 14

4.4. QAbstractButton 15

4.5. QPushButton 15

4.6. Qt之QToolButton: 15

4.7. QCheckBox: 16

4.8. QRadioButton 17

4.9. QSpinBox和QDoubleSpinBox: 18

4.10. QSlider 18

4.11. QProgressBar 20

4.12. QDateTimeEdit: 20

4.13. QDateEdit和QTimeEdit:和上面同样 21

4.14. QScrollArea 21

4.15. QToolBox 22

4.16. QSystemTrayIcon 22

公有槽函数 23

5. 布局管理器 25

5.1. QGridLayout 25

6. 数据库类型和相关类 29

6.1. QFileSystemWatcher 29

6.2. QDesktopServices 29

6.3. QTimer 30

6.4. QFileIconProvider 31

6.5. QTemporaryFile 34

6.6. QCryptographicHash: 36

公共函数 37

7. Qt 网络编程类: 39

7.1. QHostInfo 42

7.2. Address 43

7.3. QNetworkAddressEntry 44

7.4. QUrlQuery 45

7.5. QUrl 46

7.6. QHttpPartQHttpMultiPart 47

7.7. multipart 子类型: 47

7.8. QHttpPart 48

7.9. 高级网络操做(HTTP/FTP快速上手): 49

8. 线程 51

8.1. QThread - 具备可选事件循环的低级 API 51

8.2. QThreadPool 和 QRunnable - 重用线程 52

8.3. Qt Concurrent - 使用高级 API 52

8.4. WorkerScript - QML 中的线程 53

8.5. QThread 54

9. Sql部分 58

9.1. XMLEXtendsible Markup Language Lanhuage---可扩展标记语言) 58

9.2. XML(建议使用) 63

9.3. Json 70

9.4. Ini,注册表QSetting 74

10. 库和插件 78

10.1. 库 78

10.2. 插件 80

11. 绘图系统 90

12. 图形视图框架 110

13. 动画框架和状态机 124

 

 

 

1. Qt5.4.0快捷方式

.Ctrl(按住)+ Tab快速切换已打开的文件

Ctrl + Shift + R,修改变量名,并应用到全部使用该变量的地方。Alt +数字键(1-7)能够快速打开对应的输出窗口

Ctrl + M 添加/删除书签,Ctrl + . 查找并移动到下一个标签

F2 快速切换到 光标选中对象 的源码。

F4 在 头文件(.h) 和 实现文件(.cpp) 之间进行切换。

Ctrl + / 注释/取消注释选定内容。

Ctrl + i 自动缩进选中代码。

Ctrl + shift + up 将当前行的代码向上移动一行。

Ctrl + shift + down 将当前行的代码向下移动一行。

 

 

 

 

 

 

2. 信号槽机制

QObject::connect(btn,SIGNAL(clicked()),this.(quit()));

==(btn,“clicked()”,this,”quit()”)

SIGNALSLOT返回的是const chart*

一个信号能够对应多个槽,可是槽发生的前后顺序时随机的。

 

(1).宏定义不能在signalslot参数里,signalslot参数个数和类型必须一致。slot能够少的参数是signal的后面的参数

(2)signalslot不须要知道彼此的存在

 

 

 

 

 

 

 

 

 

 

 

 

3. 窗口

Qwidget,QDialog,QMainwindow的异同

 

QMainWindow类提供一个有菜单条、工具栏、状态条的主应用程序窗口(例如:开发Qt经常使用的IDE-Visual Studio、Qt Creator等)。

QMainWindow拥有本身的布局,咱们可使用QMenuBar(菜单栏)、QToolBar(工具栏)、QStatusBar(状态栏)以及QDockWidget(悬浮窗体),布局有一个可由任何种类小窗口所占据的中心区域。

3.1. 模式对话框

模式对话框有本身的事件循环,用户必须完成这个对话框中的交互操做,而且关闭了它以后才能访问应用程序中的其它任何窗口。他会调用exec(),当接收到信号,才开始下一个操做。

QMainWindow *mainwindown=new QMainWindow();

mainwindown->setWindowTitle("主界面");

QDialog *pDialog = new QDialog(this);

pDialog->setWindowTitle(QStringLiteral("模式对话框"));

 pDialog->show();

  // 关键代码

  pDialog->exec();// 关闭模态对话框之后才会执行下面的代码

  mainwindown->show();

3.2. 非模式对话框

与上面的相反,不会阻塞,能够继续执行主窗口。

3.3. 半模式对话框

// 关键代码 pDialog->setModal(true); pDialog->show(); 取消了长时间的等待。

 

 

 

 

 

 

 

4. 基本元素

 

4.1. QLable:

QLabel提供了一个文本或图像的显示,没有提供用户交互功能。

一个QLabel能够包含如下任意内容类型:

内容

设置

纯文本

使用setText()设置一个QString

富文本

使用setText()设置一个富文本的QString

图像

使用setPixmap()设置一个图像

动画

使用setMovie()设置一个动画

数字

使用setNum()设置int或double,并转换为纯文本。

Nothing

空的纯文本,默认的,使用clear()设置

    QLabel *qlabel=new QLabel();

    /*

     * QPixmap pixmap(":/Images/logo");            //显示图片     *pLabel->setPixmap(pixmap);

    */

    /*

     * QMovie *pMovie = new QMovie(":/Images/movie");//显示动画

    *pLabel->setMovie(pMovie);

    *pLabel->setFixedSize(135, 200);//设置大小

    *pLabel->setScaledContents(true);

    *pMovie->start();

    */

    /*

     * pLabel->setText(QString("<a href = \"%1\">%2</a>").arg("http://blog.csdn.net/liang19890820").arg(QStringLiteral("一去丶二三里")));

     *pLabel->setOpenExternalLinks(true);//容许打开连接

    */

    QString strHTML = QString("<html> \

                               <head> \

                               <style> \

                               font{color:blue;} #f{font-size:18px; color: green;} \

                               </style> \

                               </head> \

                               <body>\

                               <font>%1</font><font id=\"f\">%2</font> \

                               <br/><br/> \

                               </body> \

                               </html>").arg("I am a ").arg("Qter");

    qlabel->setText(strHTML);

    qlabel->setAlignment(Qt::AlignCenter);

    qlabel->setFixedSize(400,400);

    qlabel->show();

 

4.2. QLineEdit

QLineEdit是一个单行文本输入框。

QLineEdit容许用户输入和编辑单行纯文本,提供了不少有用的编辑功能,包括:撤消和重作、剪切和粘贴、以及拖放(见setDragEnabled())。

经过改变输入框的echoMode(),同时也能够设置为一个只写字段,用于输入密码等。

文本的长度能够被限制为maxLength(),可使用一个validator()inputMask()来任意限制文本。当在同一个输入框中切换验证器和输入掩码的时候,最好是清除验证器或输入掩码,防止不肯定的行为。

信号:当文本改变时,会发射textChanged()信号。

当使用setText()改变文本时,textEdited()信号也会发射。

光标位置发生变化时,会发射cursorPositionChanged()信号

ReturnEnter键被按下时,发射returnPressed()信号。

当编辑完成,或者是由于输入框失去焦点,或Return/Enter键被按下时,发出的editingFinished()信号。

枚举:QLineEdit::EchoMode

描述输入框如何显示其内容。

常量

描述

QLineEdit::Normal

0

正常显示输入的字符,默认选项。

QLineEdit::NoEcho

1

不显示任何输入,经常使用于密码类型,其密码长度都须要保密的时候。

QLineEdit::Password

2

显示平台相关的密码掩码字符,而不是实际的字符输入。

QLineEdit::PasswordEchoOnEdit

3

在编辑的时候显示字符,负责显示密码类型。

经常使用接口:

QString displayText() const  或者 QString text() const 返回输入框的当前文本displaynormal时和text()同样,其余显示啥就获得啥

QString selectedText() const 返回选中的文本

QAction * addAction(const QIcon & icon, ActionPosition position) 添加action至指定位置。

void setEchoMode(EchoMode)输入框显示模式

int maxLength() const长度

void setMaxLength(int)

bool isReadOnly() const只读

void setReadOnly()

void setSelection(int start, int length) 从位置start选择文本为length个字符,容许负长度。

void setValidator(const QValidator * v) 限制输入v

Qt::Alignment alignment() const居中等

void setAlignment(Qt::Alignment flag)

QCompleter* completer() const

void setCompleter(QCompleter * c) 

void deselect() 取消选中任何已选中的文本。

信号

void selectionChanged() 
只要选择改变这个信号就会被发射。

void cursorPositionChanged(int old, int new) 
只要光标移动,这个信号就会发射。前面的位置old,新的位置是new。

void editingFinished()

void returnPressed()

void textChanged(const QString & text)

void textEdited(const QString & text) 

共有槽

void clear() 
清除输入框内容

void copy() const 
若是echoMode()是Normal,将选中的文本复制到剪贴板。

void cut() 
若是echoMode()是Normal,将所选文本复制到剪贴板并删除它。 
若是当前的验证不容许删除选定的文本,cut()将复制而不删除。

void paste() 
若是输入框不是只读的,插入剪贴板中的文本到光标所在位置,删除任何选定的文本。 
若是最终的结果不被当前的验证器接受,将没有任何反应。

void redo() 
重作上次操做,若是redo可用(isRedoAvailable() )。

void selectAll() 
选中全部文本(即:高亮),并将光标移动到末尾。当一个默认值被插入时,这很是有用,由于若是用户在点击部件以前就输入,选中的文本将被删除。

void setText(const QString &) 
设置输入框显示的文本。

void undo() 
撤消上次操做,若是撤消可用( isUndoAvailable())。取消任何当前的选中,并更新选中到当前光标位置。

    QLineEdit *pIntLineEdit = new QLineEdit();              // 整形 范围:[1, 99]

    pIntLineEdit->setPlaceholderText(QString::fromLocal8Bit("整形"));

    QIntValidator *pIntValidator = new QIntValidator();

    pIntValidator->setRange(1, 99);

    pIntLineEdit->setValidator(pIntValidator);              //控制输入格式

    

    QLineEdit *pValidatorLineEdit = new QLineEdit(this);    // 字符和数字

    pValidatorLineEdit->setPlaceholderText(QString::fromLocal8Bit("字母和数字"));

    QRegExp reg("[a-zA-Z0-9]+$");

    QRegExpValidator *pValidator = new QRegExpValidator(this);

    pValidator->setRegExp(reg);

    pValidatorLineEdit->setValidator(pValidator);

    

    /*

    *字符含义

AASCII字母字符是必须的,A-Za-z

aASCII字母字符是容许的,但不是必须的。

NASCII字母字符是必须的,A-Za-z0-9

nASCII字母字符是容许的,但不是必须的。

X任何字符都是必需要的。

x任何字符都是容许的,但不是必需要的。

9ASCII数字是必需要的,0-9

0ASCII数字是容许的,但不是必需要的。

DASCII数字是必需要的,1-9

dASCII数字是容许的,但不是必需要的 (1-9)

#ASCII数字或加/减符号是容许的,但不是必需要的。

H十六进制数据字符是必需要的,A-Fa-f0-9

h十六进制数据字符是容许的,但不是必需要的。

B二进制数据字符是必需要的,0-1

b二进制数据字符是容许的,但不是必需要的。

>全部的字符字母都大写

<全部的字符字母都小写

!关闭大小写转换

\使用 \ 去转义上述列出的字符。

掩码由掩码字符和分隔符字符串组成,后面能够跟一个分号和用于空白的字符,空白字符在编辑后老是从文本中删除。

    */

    QLineEdit *pIPLineEdit = new QLineEdit(this);

    pIPLineEdit->setInputMask("000.000.000.000;_");

    

    QLineEdit *pPasswordLineEdit = new QLineEdit();

    pPasswordLineEdit->setPlaceholderText("Password");      //输入前的提示

pPasswordLineEdit->setEchoMode(QLineEdit::Password);    //输入的格式

 

 

4.3. QLCDNumbe

能够显示十进制、十六进制、八进制或二进制数。

接口

描述

setDigitCount(int numDigits)

设置所显示的位数

setBinMode()

以二进制形式显示

setOctMode()

以八进制形式显示

setHexMode()

以十六进制形式显示

setDecMode()

以十进制形式显示(默认)

setSmallDecimalPoint(bool)

其参数设置为true或者false,决定了小数点单独站一位空间仍是在两个位之间。换句话说,若是参数为true,小数点将占用比日常更少的空间

setSegmentStyle(SegmentStyle)

改变现实数字的外观,包括:Outline、Filled、Flat

checkOverflow(double num)

检查给定值是否能够在区域内显示(也会发射overflow()信号,能够将其链接到槽中处理)

 

 

 

4.4. QAbstractButton

QAbstractButton提供了点击和勾选按钮。QRadioButton和QCheckBox类只提供了勾选按钮,QPushButton和QToolButton提供了点击按钮,若是须要的话,它们还能够提供切换行为。

状态isDown()是否按下isCheced()是否选择isEnabled()是否可被按下setToggleButton()是否切换另外一个按钮

信号:pressed()按下release()释放clicked()点击toggled()状态变化

若是继承此类,不得不实现虚函数,paintEvent(),若是多选,放进去组里面就好。

4.5. QPushButton

主要涉及setAutoDefault、setDefault、setMenu

// 设置菜单 pButton->setMenu(pMenu);

4.6. Qt之QToolButton:

void setMenu(QMenu * menu) 
设置按钮的弹出菜单。和QPushButton用法相似

常量

 

Qt::NoArrow

0

 

Qt::UpArrow

1

 

Qt::DownArrow

2

 

Qt::LeftArrow

3

 

Qt::RightArrow

4

 

void setPopupMode(ToolButtonPopupMode mode) 
设置弹出菜单的方式,默认状况下,设置为DelayedPopup(延迟弹出)。

 

 

QToolButton *pButton = new QToolButton(this); pButton->setArrowType(Qt::LeftArrow); pButton->setText("Left Arrow"); // 文本位于图标之下 pButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); pButton->setStyleSheet("QToolButton{border: none; background: rgb(68, 69, 73); color: rgb(0, 160, 230);}");

4.7. QCheckBox:

Qt::CheckState checkState() const 
返回复选框的选中状态。若是不须要三态的支持,可使用QAbstractButton::isChecked(),它返回一个布尔值。

bool isTristate() const 
复选框是否为一个三态复选框。

默认的是false,也就是说复选框只有两个状态。

void setCheckState(Qt::CheckState state) 
设置复选框的选中状态。若是不须要三态的支持,可使用QAbstractButton:setChecked(),它接受一个布尔值。

void setTristate(bool y = true) 
设置复选框为一个三态复选框。

void stateChanged(int state) 
当复选框状态发生改变,这个信号就会被发射。即:用户选中或者取消选中。

Example:// 开启三态模式 pCheckBox->setTristate();

void MainWindow::onStateChanged(int state)

{

    if (state == Qt::Checked)                // "选中"

    { 

        m_pLabel->setText("Checked"); 

    }

    else if(state == Qt::PartiallyChecked)   // "半选"

    {

        m_pLabel->setText("PartiallyChecked");

    }

    else                                   // 未选中 Qt::Unchecked 

    {

        m_pLabel->setText("Unchecked");

    }

}

4.8. QRadioButton

4.9. QSpinBox和QDoubleSpinBox:

QspinBox微调框

QSpinBox *pSpinBox = new QSpinBox(this);

pSpinBox->setRange(20, 200);  // 范围

pSpinBox->setSingleStep(10); // 步长

pSpinBox->setValue(150);  // 当前值

pSpinBox->setPrefix("$ ");  // 前缀

pSpinBox->setSuffix(" %");  // 后缀

pSpinBox->setWrapping(true);  // 开启循环

能够子类化QSpinBox,重写valueFromText()和textFromValue()。能够重写知足要求

4.10. QSlider

QSlider部件提供了一个垂直或水平滑动条。

信号

描述

valueChanged()

当滑块的值发生了改变,发射此信号。tracking()肯定在用户交互时,是否发出此信号。

sliderPressed()

当用户按下滑块,发射此信号。

sliderMoved()

当用户拖动滑块,发射此信号。

sliderReleased()

当用户释放滑块,发射此信号。

枚举 QSlider::TickPosition

这个枚举指定刻度线相对于滑块和用户操做的位置。

常量

描述

QSlider::NoTicks

0

不绘制任何刻度线

QSlider::TicksBothSides

3

在滑块的两侧绘制刻度线

QSlider::TicksAbove

1

在(水平)滑块上方绘制刻度线

QSlider::TicksBelow

2

在(水平)滑块下方绘制刻度线

QSlider::TicksLeft

TicksAbove

在(垂直)滑块左侧绘制刻度线

QSlider::TicksRight

TicksBelow

在(垂直)滑块右侧绘制刻度线

int nMin = 0;

int nMax = 200;

int nSingleStep = 10;

 

 

QSpinBox *pSpinBox = new QSpinBox(this);        // 微调框

pSpinBox->setMinimum(nMin);                     // 最小值

pSpinBox->setMaximum(nMax);                     // 最大值

pSpinBox->setSingleStep(nSingleStep);           // 步长

 

                                        

QSlider *pSlider = new QSlider(this);           // 滑动条

pSlider->setOrientation(Qt::Horizontal);        // 水平方向

pSlider->setMinimum(nMin);                      // 最小值

pSlider->setMaximum(nMax);                      // 最大值

pSlider->setSingleStep(nSingleStep);            // 步长

 

// 链接信号槽(相互改变)

connect(pSpinBox, SIGNAL(valueChanged(int)), pSlider, SLOT(setValue(int)));

connect(pSlider, SIGNAL(valueChanged(int)), pSpinBox, SLOT(setValue(int)));

 

pSpinBox->setValue(10);

4.11. QProgressBar

pProgressBar2->setInvertedAppearance(true); // 反方向

QProgressBar *pProgressBar = new QProgressBar(this);

pProgressBar->setOrientation(Qt::Horizontal);     // 水平方向

pProgressBar->setMinimum(0);                        // 最小值

pProgressBar->setMaximum(4800);                     // 最大值

pProgressBar->setValue(2000);                       // 当前进度

double dProgress = (pProgressBar->value() - pProgressBar->minimum()) * 100.0

                / (pProgressBar->maximum() - pProgressBar->minimum());

pProgressBar->setFormat(QString::fromLocal8Bit("当前进度为:%1%").arg(QString::number(dProgress, 'f', 1)));

pProgressBar->setAlignment(Qt::AlignRight | Qt::AlignVCenter);  // 对齐方式

 

 

 

4.12. QDateTimeEdit:

提供了一个部件,用于编辑日期和时间。

QDateTimeEdit *dateTimeEdit = new QDateTimeEdit(this); QDateTimeEdit *dateTimeEdit2 = new QDateTimeEdit(QDateTime::currentDateTime(), this); QDateTimeEdit *dateEdit = new QDateTimeEdit(QDate::currentDate(), this); QDateTimeEdit *timeEdit = new QDateTimeEdit(QTime::currentTime(), this);

 

能够设置日期格式

// 设置日期时间格式

 dateTimeEdit->setDisplayFormat("yyyy-MM-dd HH:mm:ss"); dateTimeEdit2->setDisplayFormat("yyyy/MM/dd HH-mm-ss"); dateEdit->setDisplayFormat("yyyy.M.d"); timeEdit->setDisplayFormat("H:mm");

dateEdit->setMinimumDate(QDate::currentDate().addDays(-365)); // -365天 dateEdit->setMaximumDate(QDate::currentDate().addDays(365)); // +365天

setCalendarPopup(true)//显示日历

信号:dateChanged()、dateTimeChanged()、timeChanged(),当日期、日期时间、时间改变时发射。

4.13. QDateEdit和QTimeEdit和上面同样

4.14. QScrollArea

提供了一个滚动视图到另外一个部件

QLabel *imageLabel = new QLabel(this);

QPixmap pixmap(":/Images/head");

pixmap = pixmap.scaled(200, 200, Qt::KeepAspectRatio);  // 图片缩放

imageLabel->setPixmap(pixmap);

imageLabel->setStyleSheet("background: white;");  // 标签白色背景

imageLabel->setAlignment(Qt::AlignCenter);  // 图片居中

 

QScrollArea *scrollArea = new QScrollArea(this);

scrollArea->setBackgroundRole(QPalette::Dark);  // 背景色

scrollArea->setWidget(imageLabel);

scrollArea->setAlignment(Qt::AlignCenter);  // 居中对齐

scrollArea->setWidgetResizable(true);  // 自动调整大小

scrollArea->setWidget(imageLabel);

 

QWidget *widget = scrollArea->widget();//获取部件

QWidget *widget = scrollArea->takeWidget();//一移除部件

QLabel *pLabel = qobject_cast<QLabel *>(widget);

4.15. QToolBox

提供了一个列(选项卡式的)部件条目

每一个item都有一个itemText()、一个可选的itemIcon()、一个可选的itemToolTip()、和一个widget()函数 。item的属性能够经过setItemText()、setItemIcon()、和setItemToolTip()来改变,而且每一个item能够经过setItemEnabled()单独设置为是否可用。

Item的添加使用addItem(),或经过insertItem()在特定位置插入。若是要获取items的总数,能够调用count()函数。Item可使用removeItem()从toolbox中删除。结合removeItem()和insertItem(),容许你将item移动到不一样的位置。

当前item部件的索引由currentIndex()返回,并使用setCurrentIndex()来设置。一个特定item的索引可使用indexOf()来获取,item()则返回给定索引的item。

当前的item发生变化时,会发射currentChanged()信号。

4.16. QSystemTrayIcon

为应用程序在系统托盘中提供一个图标

要检查系统托盘是否存在在用户的桌面上,调用QSystemTrayIcon::isSystemTrayAvailable()静态函数。

公有槽函数:

void hide() 隐藏系统托盘。

void setVisible(bool visible) 设置系统托盘是否可见。

设置为true或调用show()使系统托盘图标可见;设置为false或调用hide()隐藏它。

void show() 显示系统托盘。

void showMessage(const QString & title, const QString & message, QSystemTrayIcon::MessageIcon icon = QSystemTrayIcon::Information, int millisecondsTimeoutHint = 10000) 
显示一个气球消息,使用所给出的标题、消息、图标和指定的时间,标题和消息必须是纯文本字符串。

消息能够被用户点击,当用户点击时发出messageClicked()信号 。

信号:

void activated(QSystemTrayIcon::ActivationReason reason) 
当用户激活系统托盘图标,这个信号被发射。reason指定激活的缘由, QSystemTrayIcon::ActivationReason列举了各类缘由。

void messageClicked() 
当使用showMessage()显示的消息被用户点击时,此信号被发射。

QSystemTrayIcon *pSystemTray = new QSystemTrayIcon(this); TrayMenu *pTrayMenu = new TrayMenu(this); // 设置系统托盘的上下文菜单 pSystemTray->setContextMenu(pTrayMenu); // 设置系统托盘提示信息、托盘图标 pSystemTray->setToolTip(QString::fromLocal8Bit("我就是托盘")); pSystemTray->setIcon(QIcon(":/icon/login")); // 链接信号槽 connect(pTrayMenu, SIGNAL(showWindow()), this, SLOT(showWindow())); connect(pSystemTray , SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(onActivated(QSystemTrayIcon::ActivationReason))); // 显示系统托盘 pSystemTray->show(); // 显示系统托盘提示信息 pSystemTray->showMessage(QString::fromLocal8Bit("托盘标题"), QString::fromLocal8Bit("托盘显示内容"));

 

 

 

 

 

 

 

 

 

 

 

 

 

5. 布局管理器

5.1. QGridLayout:

 

 

// 记住密码 第2行,第1列开始,占1行1列 水平居左 垂直居中 pLayout->addWidget(pRememberCheckBox, 2, 1, 1, 1, Qt::AlignLeft | Qt::AlignVCenter);

pLayout->setHorizontalSpacing(10); // 设置水平间距pLayout->setVerticalSpacing(10); // 设置垂直间距 pLayout->setContentsMargins(10101010);// 设置外间距 

pImageLabel->setScaledContents(true);//图片只适应大小

setRowMinimumHeight(int row, int minSize) 设置行最小高度

setColumnMinimumWidth(int column, int minSize) 设置列最小宽度

columnCount()获取列数

rowCount() 获取行数

setOriginCorner(Qt::Corner)设置原始方向

setRowStretch(int row, int stretch)

setColumnStretch(int column, int stretch)设置行/列的伸缩空间

QBoxlayout:

  pHLayout->addStretch();  // 添加伸缩,在左边添加,这样就会居右显示,可居中,均分,居左

    pHLayout->setMargin(100);//外边距100

    pHLayout->setSpacing(100);//间距

    pHLayout->setStretchFactor(two, 2);//拉伸系数

    pHLayout->setDirection(QBoxLayout::RightToLeft);//布局方向

pHLayout->setContentsMargins(50,20,20,20);//widget之间左上右下的边距

QStackedLayout:

类提供了多页面切换的布局,一次只能看到一个界面。

QPushButton *pButton = new QPushButton(this);

QLabel *pFirstPage= new QLabel(this);

QLabel *pSecondPage = new QLabel(this);

QLabel *pThirdPage = new QLabel(this);

m_pStackedLayout = new QStackedLayout();

 

pButton->setText(QStringLiteral("点击切换"));

pFirstPage->setText(QStringLiteral("一去丶二三里"));

pSecondPage->setText(QStringLiteral("青春不老,奋斗不止!"));

pThirdPage->setText(QStringLiteral("纯正开源之美,有趣、好玩、靠谱。。。"));

 

// 添加页面(用于切换)

m_pStackedLayout->addWidget(pFirstPage);

m_pStackedLayout->addWidget(pSecondPage);

m_pStackedLayout->addWidget(pThirdPage);

 

QVBoxLayout *pLayout = new QVBoxLayout();

pLayout->addWidget(pButton, 0, Qt::AlignLeft | Qt::AlignVCenter);

pLayout->addLayout(m_pStackedLayout);

pLayout->setSpacing(10);

pLayout->setContentsMargins(10, 10, 10, 10);

setLayout(pLayout);

 

// 链接切换按钮信号与槽

connect(pButton, &QPushButton::clicked, this, &MainWindow::switchPage);

 

// 切换页面

void MainWindow::switchPage()

{

    int nCount = m_pStackedLayout->count();

    int nIndex = m_pStackedLayout->currentIndex();

 

    // 获取下一个须要显示的页面索引

    ++nIndex;

 

    // 当须要显示的页面索引大于等于总页面时,切换至首页

    if (nIndex >= nCount)

        nIndex = 0;

 

    m_pStackedLayout->setCurrentIndex(nIndex);

}

手动布局:

void MainWindow::resizeEvent(QResizeEvent *event)

{

    QWidget::resizeEvent(event);

 

    int nSpacing = 10;

    int nLeft = 10;

    int nTop = 10;

    int nRight = 10;

    int nBottom = 10;

 

    // 标签位置、大小

    m_pLabel->setGeometry(nLeft, nTop, width() - nLeft - nRight, 20);

 

    // 按钮大小

    m_pButton->setFixedSize(75, 25);

 

    // 设置按钮位置

    m_pButton->move(width() - m_pButton->width() - nRight, height() - nBottom - m_pButton->height());

 

    // 中央窗体位置、大小

    m_pCentralWidget->setGeometry(nLeft, nTop + nSpacing + m_pLabel->height(),

                                  width() - nLeft - nRight, height() - nTop - 2 *nSpacing - m_pLabel->height() - m_pButton->height() - nBottom);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

6. 数据库类型和相关类

6.1. QFileSystemWatcher

提供监视文件和目录修改的接口

公共函数:

bool addPath(const QString & path) 存在则添加监控

QStringList addPaths(const QStringList & paths) 返回值是不能添加的列表

QStringList directories() const返回被监控目录的路径列表

QStringList files() const返回被监控文件的路径列表

bool removePath(const QString & path) 移除指定路径

QStringList removePaths(const QStringList & paths) 

信号:

void directoryChanged(const QString & path) 目录被修改触发

void fileChanged(const QString & path) 文件被修改

6.2. QDesktopServices

提供的函数用于访问常见的桌面服务。如用chorme打开www.baidu.com

静态共有函数:

bool openUrl(const QUrl & url);

QDesktopServices::openUrl(QUrl("http://www.baidu.com"));

QDesktopServices::openUrl(QUrl("file:///D:/Program Files/Youdao"));

void setUrlHandler(const QString & scheme, QObject * receiver, const char * method)这个函数提供了一种方法来定制openUrl()行为。若是以指定的scheme调用openUrl()(带参数URL),接受者指定的函数将被调用来代替QDesktopServices启动外部应用程序。

6.3. QTimer

提供了重复和单次触发信号的定时器。

QTimer *timer = new QTimer(this); 

connect(timer, SIGNAL(timeout()), this, SLOT(update())); 

timer->start(1000);

QTimer::singleShot(200, this, SLOT(updateCaption()));//单次执行

精度枚举Qt::TimerType:

常量

描述

Qt::PreciseTimer

0

精确的定时器,尽可能保持毫秒精度。

Qt::CoarseTimer

1

粗略的定时器,尽可能保持精度在所需的时间间隔5%范围内。

Qt::VeryCoarseTimer

2

很粗略的定时器,只保留完整的第二精度。

成员函数:

bool isActive() const 若是定时器正在运行,返回true,不然返回false。

int remainingTime() const返回定时器的剩余时间(毫秒为单位),直到超时。若是定时器不活跃,返回值是-1。若是定时器过时,返回值为0。

void setInterval(int msec) 设置超时间隔(毫秒为单位)。

默认值是0,这时,一旦窗口系统事件队列中的全部事件都已经被处理完,一个时间间隔为0的QTimer就会触发。

void setSingleShot(bool singleShot) 设置定时器是否为单次触发。

单次触发定时器只触发一次,非单次的话,则每过一个时间间隔都会触发。

void setTimerType(Qt::TimerType atype) 
设置定时器的准确性。默认值是Qt::CoarseTimer。

int timerId() const 若是定时器正在运行,返回定时器的ID,不然返回-1。

void start(int msec) 启动或从新启动一个超时时间间隔为毫秒的定时器。

若是定时器正在运行,它将被中止和从新启动。若是singleShot为true,定时器将只激活一次。

void start() 同上,重载了start()。

void stop() 中止定时器。

信号:

void timeout() 定时器超时后,这个信号被发射。

注意:这是一个私有的信号。它能够在信号链接使用,但不能由用户发出。

6.4.  QFileIconProvider

为QDirModel和QFileSystemModel类提供了文件图标。

枚举QFileIconProvider::IconType:

常量

QFileIconProvider::Computer

0

QFileIconProvider::Desktop

1

QFileIconProvider::Trashcan

2

QFileIconProvider::Network

3

QFileIconProvider::Drive

4

QFileIconProvider::Folder

5

QFileIconProvider::File

6

公共函数:

QIcon icon(IconType type) const 获取IconType图标类型对应的图标。

QIcon icon(const QFileInfo & info) const 获取QFileInfo文件信息对应的图标。

Options options() const 获取全部影响QFileIconProvider的选项。默认状况下,全部选项被禁用。

void QFileIconProvider::setOptions(Options options) 设置全部影响QFileIconProvider的选项。

QString type(const QFileInfo & info) const 获取QFileInfo文件信息对应的类型描述。

QListWidget *pListWidget = new QListWidget(this);

pListWidget->setIconSize(QSize(48, 48));         // 设置单元项图片大小

pListWidget->setResizeMode(QListView::Adjust);   // 设置大小模式-可调节

pListWidget->setViewMode(QListView::IconMode);   // 设置显示模式

pListWidget->setMovement(QListView::Static);     // 设置单元项不可被拖动

pListWidget->setSpacing(10);                     // 设置单元项间距

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

    {

        // 获取图标

        QFileIconProvider provider;

        QIcon icon = provider.icon((QFileIconProvider::IconType)i);

 

        // 添加单元项

        QListWidgetItem *pItem = new QListWidgetItem(pListWidget);

        pItem->setIcon(icon);

        pListWidget->addItem(pItem);

}

 

    QListWidget *pListWidget = new QListWidget(this);

    pListWidget->resize(500,500);

    QStringList strList;

    strList << QString::fromLocal8Bit("新建文件夹");

 

   QFileInfo info;

   info.setFile(QString("/home/zz/qt/%1").arg(strList.at(0)));

 

   QFileeIconProvider provider;

   QIcon icon = provider.icon(info);

   QString strType = provider.type(info);

 

   QListWidgetItem *pItem = new QListWidgetItem(pListWidget);

   pItem->setIcon(icon);

   pItem->setText(strType);

   pListWidget->addItem(pItem);

 

 

6.5. QTemporaryFile:

临时文件放在临时文件夹,不能够指定去命名,由系统自动分配一个惟一的名字。QTemporaryFile file;

if (file.open()) {

    // file.fileName() 返回惟一的文件名

}

 

// QTemporaryFile析构,移除临时文件

经常使用接口:

void setAutoRemove(bool b) 
设置是否为自动删除模式。默认状况下,自动删除模式打开。

bool open() 
QTemporaryFile在QIODevice::ReadWrite(读写)模式下老是打开的,这方便访问文件中的数据。成功时返回true,将设置fileName()为惟一的文件名。

void setFileTemplate(const QString & name) 
设置文件模板。默认文件模板为qcoreappname.XXXXXX,被放置在QDir::tempPath()目录中。

virtual QString fileName() const 
从新实现QFileDevice::fileName()获取完整的惟一文件名。在QTemporaryFile打开以前,返回值为空,以后将包含fileTemplate(),加上其它的字符使其惟一。

QTemporaryFile * createNativeFile(QFile & file) 
建立本地临时文件若是文件不是本地文件,使用QDir::tempPath()建立一个QTemporaryFile,将文件的内容复制给它。若是文件是一个本地文件,返回0,什么都不作。

 QApplication a(argc, argv);

    // 设置模板名称

    QString strFileName = QDir::tempPath() + QDir::separator() +

                QCoreApplication::applicationName() + "_XXXXXX." + "docx";

    QTemporaryFile tmpFile(strFileName);

 

    // 设置为不自动删除

    tmpFile.setAutoRemove(false);

 

    qDebug() << "tempPath : " << QDir::tempPath();

 

    if (tmpFile.open())

    {

        tmpFile.close();

 

        QString strFileTemplate = tmpFile.fileTemplate();

        QString strFileName = tmpFile.fileName();

 

        qDebug() << "fileTemplate : " << strFileTemplate;

        qDebug() << "fileName : " << strFileName;

        // tmpFile.remove();能够手动删除

    }

    else

    {

        qCritical() << "failed to write temporary file";

}

 

 

6.6.  QCryptographicHash:

供了生成密码散列的方法。该类能够用于生成二进制或文本数据的加密散列值。目前支持MD四、MD五、SHA-一、SHA-22四、SHA-25六、SHA-384和SHA-512。

枚举QCryptographicHash::Algorithm:

常量

取值

描述

QCryptographicHash::Md4

0

生成一个MD4散列

QCryptographicHash::Md5

1

生成一个MD5散列

QCryptographicHash::Sha1

2

生成一个SHA-1散列

QCryptographicHash::Sha224

3

生成一个SHA-224散列(SHA-2)

QCryptographicHash::Sha256

4

生成一个SHA-256散列(SHA-2)

QCryptographicHash::Sha384

5

生成一个SHA-384散列(SHA-2)

QCryptographicHash::Sha512

6

生成一个SHA-512散列(SHA-2)

QCryptographicHash::Sha3_224

7

生成一个SHA3-224散列

QCryptographicHash::Sha3_256

8

生成一个SHA3-256散列

QCryptographicHash::Sha3_384

9

生成一个SHA3-384散列

QCryptographicHash::Sha3_512

10

生成一个SHA3-512散列

 

公共函数

· 

void addData(const char * data, int length) 
将第一个字符长度的数据添加到密码散列。

bool addData(QIODevice * device) 
从开放的QIODevice设备读取数据,直到结束并计算出哈希值。若是成功读取,返回true。

void addData(const QByteArray & data) 
这个函数重载了addData()。

void reset() 
重置对象。

QByteArray result() const 
获取最终的哈希值。

QByteArray hash(const QByteArray & data, Algorithm method) 
获取data数据的哈希值。

 QByteArray hash = QCryptographicHash::hash("i love you", QCryptographicHash::Md5);

 qDebug()<<hash.toHex();

 

QCryptographicHash hash(QCryptographicHash::Md5);

    hash.addData("始于颜值,敬于才华,合于性格,久于善良,终于人品");  // 添加数据到加密哈希值

    qDebug()<<hash.result().toHex();

 

 

 

 

 

 

 

 

 

 

 

 

 

7. Qt 网络编程类:

描述

QAbstractNetworkCache

为缓存实现的接口

QAbstractSocket

包含全部 socket 类型的基础功能

QAuthenticator

认证对象

QDnsDomainNameRecord

存储关于域名记录的信息

QDnsHostAddressRecord

存储关于主机地址记录的信息

QDnsLookup

表示一个DNS查询

QDnsMailExchangeRecord

存储有关 DNS MX 记录的信息

QDnsServiceRecord

存储有关 DNS SRV 记录的信息

QDnsTextRecord

存储有关 DNS TXT 记录的信息

QHostAddress

IP地址

QHostInfo

主机名查询静态函数

QHttpMultiPart

相似于一个 MIME 多个部分消息,经过HTTP发送

QHttpPart

持有一个 body 部分,用于 HTTP 多个部分的 MINE 消息

QLocalServer

本地 socket 依赖的 server

QLocalSocket

本地 socket

QNetworkAccessManager

容许程序发送网络请求和接收响应

QNetworkAddressEntry

存储一个 IP 地址,经过网络接口的支持,连同相关的网络掩码和广播地址

QNetworkCacheMetaData

缓存信息

QNetworkConfiguration

一个或多个配置接入点的抽象概念

QNetworkConfigurationManager

管理由系统提供的网络配置

QNetworkCookie

管理由系统提供的网络配置

QNetworkCookieJar

实现 QNetworkCookie 对象的一个简单jar

QNetworkDiskCache

很是基本的磁盘缓存

QNetworkInterface

主机的IP地址和网络接口列表

QNetworkProxy

网络层代理

QNetworkProxyFactory

精细的代理选择

QNetworkProxyQuery

用于查询一个 socket 的代理设置

QNetworkReply

包含 QNetworkAccessManager 发送的请求数据和消息头

QNetworkRequest

持有一个 QNetworkAccessManager 发送的请求

QNetworkSession

控制系统的接入点并启用例的会话管理,为了当多个客户端访问相同的接入点

QSslCertificate

用于 X509 证书的方便 API

QSslCertificateExtension

用于访问 X509 证书扩展的API

QSslCipher

表明一个SSL加密密码

QSslConfiguration

持有 SSL 链接的配置及状态

QSslEllipticCurve

表明了一种椭圆曲线使用椭圆曲线密码算法

QSslError

SSL 错误

QSslKey

私钥和公钥的接口

QSslPreSharedKeyAuthenticator

预共享密钥认证数据(PSK)密码套件

QSslSocket

clients 和 servers 的 SSL 加密 socket

QTcpServer

基于 TCP 的 server

QTcpSocket

TCP socket

QUdpSocket

UDP socket

 

 

 

 

· 

QT += network

#include <QtNetwork>

7.1. QHostInfo

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

{

    QApplication a(argc,argv);

    Form w;

    w.show();

    QHostInfo infolocal=QHostInfo::fromName(QHostInfo::localHostName());

    w.ui->textBrowser->append(QHostInfo::localHostName());

    foreach (QHostAddress str, infolocal.addresses())

    {

        w.ui->textBrowser->append(str.toString());

    }

 

 

    QHostInfo info=QHostInfo::fromName("www.baidu.com");

    w.ui->textBrowser->append(info.hostName());

    foreach (QHostAddress str, info.addresses())

    {

        w.ui->textBrowser->append(str.toString());

    }

    return a.exec();

}

 

7.2. Address

QHostAddress add=QHostAddress(QHostAddress::AnyIPv6);

QList<QHostAddress> list = QNetworkInterface::allAddresses();

    foreach (QHostAddress address, list)

    {

        if (address.isNull())

            continue;

        w.ui->textBrowser->append( "********************");

        QAbstractSocket::NetworkLayerProtocol nProtocol = address.protocol();

        QString strScopeId = address.scopeId();

        QString strAddress = address.toString();

        bool bLoopback = address.isLoopback();

 

        // 若是是IPv4

        if (nProtocol == QAbstractSocket::IPv4Protocol) {

            bool bOk = false;

            quint32 nIPV4 = address.toIPv4Address();

            if (bOk)

                w.ui->textBrowser->append("IPV4 : "+ nIPV4);

        }

        // 若是是IPv6

        else if (nProtocol == QAbstractSocket::IPv6Protocol) {

            QStringList IPV6List("");

            Q_IPV6ADDR IPV6 = address.toIPv6Address();

            for (int i = 0; i < 16; ++i) {

                quint8 nC = IPV6[i];

                IPV6List << QString::number(nC);

            }

            w.ui->textBrowser->append( "IPV6 : " +IPV6List.join(" "));

        }

 

        w.ui->textBrowser->append( "Protocol : " + nProtocol);

        w.ui->textBrowser->append( "ScopeId : " + strScopeId);

        w.ui->textBrowser->append( "Address : " + strAddress);

        w.ui->textBrowser->append("IsLoopback  : "+ bLoopback);

    }

 

7.3. QNetworkAddressEntry

由网络接口支持,存储了一个IP地址,子网掩码和广播地址。

经常使用接口:

QHostAddress broadcast() const

QHostAddress ip() const

QHostAddress netmask() const

QHostAddress netmask() const返回前缀长度,ipv4返回0-32,ipv6返回0-128

QList<QNetworkInterface> list = QNetworkInterface::allInterfaces();

    foreach (QNetworkInterface netInterface, list) {

        QList<QNetworkAddressEntry> entryList = netInterface.addressEntries();

        foreach(QNetworkAddressEntry entry, entryList) {  // 遍历每个IP地址

            qDebug() << "********************";

            qDebug()<<"Name:"<<netInterface.name();

            qDebug()<<"HardwareAddress:"<<netInterface.hardwareAddress();

            qDebug() << "IP Address:" << entry.ip().toString();  // IP地址

            qDebug() << "Netmask:" << entry.netmask().toString();  // 子网掩码

            qDebug() << "Broadcast:" << entry.broadcast().toString();  // 广播地址

            qDebug() << "Prefix Length:" << entry.prefixLength();  // 前缀长度

        }

    }

 

7.4.  QUrlQuery

提供了一种方法来操纵 URL 查询中的 key-value 对。

 Url的构造:

    QString baseUrl = "http://www.zhihu.com/search?";

    QByteArray bytes;

    bytes.append("type=content&");

    bytes.append(QString("q=%1").arg("Qt"));  // Qt 做为变量输入

    baseUrl += bytes;

    QUrl url(baseUrl);

    qDebug() << url;

    

    QString baseUrl = "http://www.zhihu.com/search";

    QUrl url(baseUrl);

    QUrlQuery query;

    query.addQueryItem("type", "content");

    query.addQueryItem("q", "Qt");

    url.setQuery(query);

    qDebug() << url;        

 

    QString baseUrl = "http://www.zhihu.com/search";

    QUrl url(baseUrl);

    QUrlQuery query;

    query.setQuery("type=content&q=Qt");

    url.setQuery(query);

    qDebug() << url;

 

 

7.5. QUrl

提供了一个方便的接口使用 URLs

构造:

 QUrl url("https://github.com/");

 url.setUrl("www.guet.edu.cn");

  

也能够逐渐地构造 URL,经过调用 setScheme()、setUserName()、setPassword()、setHost()、setPort()、setPath()、setQuery() 和 setFragment()。一些方便的函数也可供使用:setAuthority() 设置用户名、密码、主机和端口。setUserInfo() 设置用户名和密码。

 

 

 

 

 

深刻使用:

相对路径

 

QUrl baseUrl("http://qt.digia.com/Support/")

QUrl relativeUrl("../Product/Library/")

qDebug(baseUrl.resolved(relativeUrl).toString())// 打印 "http://qt.digia.com/Product/Library/"

 

7.6. QHttpPart和QHttpMultiPart:

7.7. multipart 子类型:

常量

描述

QHttpMultiPart::MixedType

0

对应于 "multipart/mixed" 子类型,意味着 body 部位是相互独立的。如 RFC 2046 所述。

QHttpMultiPart::RelatedType

1

对应于 "multipart/related" 子类型,意味着 body 部位是相互关联的。如 RFC 2387 所述。

QHttpMultiPart::FormDataType

2

对应 "multipart/form-data" 子类型,意味着 body 部位包含表单元素。如 RFC 2388 所述。

QHttpMultiPart::AlternativeType

3

对应 "multipart/alternative" 子类型,意味着 body 部位是相同信息的替表明示。如 RFC 2046 所述。

7.8. QHttpPart:

一个httppart有一个body,这个body由header和数据块组成

例子:

Content-Typetext/plain 

Content-Dispositionform-data; name="text"

 here goes the body

构建httppart

QHttpPart textPart; 

textPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/plain")); textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"text\"")); textPart.setBody("here goes the body");

 

QHttpPart imagePart;

   imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg"));

   imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"image\""));

   imagePart.setRawHeader("Content-ID", "my@content.id"); // 添加任何你喜欢的 headers

   QFile *file = new QFile("image.jpg");

   file->open(QIODevice::ReadOnly);

   imagePart.setBodyDevice(file);

 

 

 

QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);

 

QHttpPart textPart;

textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"text\""));

textPart.setBody("my text");

 

QHttpPart imagePart;

imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg"));

imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"image\""));

QFile *file = new QFile("image.jpg");

file->open(QIODevice::ReadOnly);

imagePart.setBodyDevice(file);

file->setParent(multiPart); // 如今不能删除文件,因此用 multiPart 删除

 

multiPart->append(textPart);

multiPart->append(imagePart);

 

QUrl url("http://my.server.tld");

QNetworkRequest request(url);

 

QNetworkAccessManager manager;

QNetworkReply *reply = manager.post(request, multiPart);

multiPart->setParent(reply); //  reply 删除 multiPart

// 这里链接信号等

 

7.9. 高级网络操做(HTTP/FTP快速上手):

在进行网络请求以前,首先,要查看 QNetworkAccessManager 支持的协议

  qDebug()<<manager->supportedSchemes();

QNetworkRequest、QNetworkReply 和 QNetworkAccessManager,使用常见的协议执行网络操做。

    // URL

    QString baseUrl = "http://www.csdn.net/";

 

    // 构造请求

    QNetworkRequest request;

    request.setUrl(QUrl(baseUrl));

 

    // 发送请求

    QNetworkAccessManager *manager = new QNetworkAccessManager();

    QNetworkReply *pReplay = manager->get(request);

    // 开启一个局部的事件循环,等待响应结束,退出

    QEventLoop eventLoop;

    QObject::connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit);

    eventLoop.exec();

 

    // 获取响应信息

    QByteArray bytes = pReplay->readAll();

    qDebug() << bytes;

HTTPS登陆

http文件下载:

 

 

 

进程间通讯:

 

 

 

 

 

事件

 

 

 

8. 线程

何为线程:简单的说就是两个相同的程序,并行的执行不一样的任务,进程则是两个不一样的程序,在用进程时注意对相同数据操做时候的数据保护,QMUtex是强制数据保护的基本类,QReadWriteLock区分了读和写的访问。QSemaphore 是 QMutex 的一个推广,能够保护必定数量相同的资源。相比之下,一个 QMutex 只能保护一个资源。QWaitCondition 同步线程,不经过执行互斥,而经过提供一个条件变量。其它原语使线程等待,直到资源被解锁;QWaitCondition 使线程等待,直到知足一个特定的条件。让等待中的线程继续进行,调用 wakeOne() 来唤醒一个随机选择的线程或 wakeAll() 同时唤醒全部。显示了如何使用 QWaitCondition 代替 QSemaphore 来实现“生产者 - 消费者”模式。

可重入和线程安全:好比一个类定义了一个整数变量和相关操做函数,由于c++的类每每是可重入的,他们操做本身的数据,固然能够重入。可是一个对象执行多个线程时,数据每每会发生混乱。这每每是不安全的。

8.1. QThread - 具备可选事件循环的低级 API

QThread 是 Qt 中全部线程控制的基础,每一个 QThread 实例表示和控制一个线程。

QThread 能够直接实例化或子类,实例化 QThread 提供了一个并行事件循环,容许在次线程中调用 QObject 的槽函数。子类化 QThread 容许应用程序在开始其事件循环以前初始化新的线程,或者运行没有事件循环的并行代码。

有关如何使用 QThread 的演示,请参阅 QThread 类参考和线程示例。

8.2. QThreadPool 和 QRunnable - 重用线程

常常建立和销毁线程多是昂贵的,为了减小这种开销,现有线程能够从新用于新任务。QThreadPool 是可重用的 QThreads 的集合。

要在 QThreadPool 的线程中运行代码,请从新实现 QRunnable::run() 并实例化子类化的 QRunnable。使用 QThreadPool::start() 将 QRunnable 放在 QThreadPool 的运行队列中。当线程可用时,QRunnable::run() 中的代码将在该线程中执行。

每一个 Qt 应用程序有一个全局线程池,可经过 QThreadPool::globalInstance() 进行访问。此全局线程池根据 CPU 中的核数自动维护最佳线程数。可是,能够显式建立和管理单独的 QThreadPool。

8.3. Qt Concurrent - 使用高级 API

Qt Concurrent 模块提供了处理一些常见并行计算模式的高级函数:map、filter 和 reduce。与使用 QThread 和 QRunnable 不一样,这些函数不须要使用低级线程原语,例如:互斥锁或信号量。相反,他们返回一个 QFuture 对象,当他们准备就绪时,可用于检索函数的结果。QFuture 也能够用于查询计算进度并暂停/恢复/取消计算。为方便起见,QFutureWatcher 经过信号和槽与 QFutures 进行交互。

Qt Concurrent 的 map、filter 和 reduce 算法在全部可用的处理器核心之间自动分配计算,所以今天编写的应用程序将在之后在具备更多核心的系统上部署时继续扩展。

这个模块还提供了 QtConcurrent::run() 函数,它能够在另外一个线程中运行任何函数。可是,QtConcurrent::run() 只支持可用于 map、filter 和 reduce 函数的一个子集。QFuture 能够用于检索函数的返回值,并检查线程是否正在运行。可是,对 QtConcurrent::run() 的调用仅使用一个线程,不能被暂停/恢复/取消,而且不能被查询进度。

有关各个功能的详细信息,请参阅 Qt Concurrent 模块文档。

8.4. WorkerScript - QML 中的线程

WorkerScript QML 类型容许 JavaScript 代码与 GUI 线程并行运行。

每一个 WorkerScript 实例能够有一个 .js 脚本附加到它。当调用 WorkerScript::sendMessage() 时,脚本将在单独的线程(和单独的 QML 上下文)中运行。当脚本完成运行时,它能够发送一个回复给 GUI 线程,它将调用 WorkerScript::onMessage() 信号处理程序。

使用 WorkerScript 相似于使用已移动到另外一个线程的工做 QObject。 数据经过信号在线程之间传输。

Concurrent

QtConcurrent::map():将一个函数应用于一个容器中的每一项,就地修改 items。

QtConcurrent::mapped():和 map() 相似,只是它返回一个包含修改内容的新容器。

QtConcurrent::mappedReduced():和 mapped() 相似,只是修改后的结果减小或组合成一个单一的结果。

QtConcurrent::filter():从一个容器中删除全部 items,基于一个 filter 函数的结果。

QtConcurrent::filtered():和 filter() 相似,只是它返回一个包含过滤内容的新容器。

QtConcurrent::filteredReduced():和 filtered() 相似,只是过滤后的结果减小或组合成一个单一的结果。

QtConcurrent::run():在另外一个线程中运行一个函数。

QFuture:表示异步计算的结果

 

QFutureIterator:容许经过 QFuture 遍历可用的结果

QFutureWatcher:容许使用信号槽来监控一个 QFuture

QFutureSynchronizer:是一个方便的类,用于一些 QFutures 的自动同步

 

8.5. QThread

启动:

void start(Priority priority = InheritPriority) 启动函数,调用时会执行run()函数,可是run()会发射started()信号,若是线程在运行,则无反应

执行:

void exec()进入事件循环并等待直到调用exit(),返回值是经过调用exit()来得到,若是调用成功则范围0

退出:

void quit() [slot] 告诉线程事件循环退出,返回0表示成功,至关于调用了QThread::exit(0)。void exit(int returnCode = 0)告诉线程事件循环退出。 调用这个函数后,线程离开事件循环后返回,QEventLoop::exec()返回returnCode,按照惯例,0表示成功;任何非0值表示失败。

void requestInterruption() 请求线程的中断。该请求是咨询意见而且取决于线程上运行的代码,来决定是否及如何执行这样的请求。此函数不中止线程上运行的任何事件循环,而且在任何状况下都不会终止它。

等待:

void requestInterruption() 请求线程的中断。该请求是咨询意见而且取决于线程上运行的代码,来决定是否及如何执行这样的请求。此函数不中止线程上运行的任何事件循环,而且在任何状况下都不会终止它。

void sleep(unsigned long secs) [static] 
强制当前线程睡眠secs秒

void usleep(unsigned long usecs) [static] 强制当前线程睡眠usecs微秒

bool wait(unsigned long time = ULONG_MAX) 线程将会被阻塞,等待time毫秒。和sleep不一样的是,若是线程退出,wait会返回。

状态:isFinisged()  isEunning()  isInterruptionRequested()

class Worker : public QObject

{

    Q_OBJECT

 

public slots:

    void doWork(const QString ¶meter) {

        QString result;

        // 这里是昂贵的或阻塞的操做

        emit resultReady(result);

    }

 

signals:

    void resultReady(const QString &result);

};

class Controller : public QObject

{

    Q_OBJECT

    QThread workerThread;

public:

    Controller() {

        Worker *worker = new Worker;

        worker->moveToThread(&workerThread);

        connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);

        connect(this, &Controller::operate, worker, &Worker::doWork);

        connect(worker, &Worker::resultReady, this, &Controller::handleResults);

        workerThread.start();

    }

    ~Controller() {

        workerThread.quit();

        workerThread.wait();

    }

public slots:

    void handleResults(const QString &);

signals:

    void operate(const QString &);

};

 

 

virtual void run()

    {

        int nValue = 0;

               while (nValue < 100)

               {

                   // 休眠50毫秒

                   msleep(50);

                   ++nValue;

 

                   // 准备更新

                   emit resultReady(nValue);

               }

    }

 

signals:

    void resultReady(int);

onnect(this,SIGNAL(resultReady(int)),this,SLOT(updateprogress(int))); connect(this,SIGNAL(finished()),this,SLOT(deleteLater()));

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

9. Sql部分

9.1. XML(EXtendsible Markup Language Lanhuage---可扩展标记语言)

两种访问xml的方式,domsax,因为dom是先储存到内存里面,对于频繁的修改很强,sax逐行扫描文档,一边扫描一边解析,随时中止。

类 描述

QDomAttr 表示一个 QDomElement 的属性

QDomCDATASection 表示一个 XML CDATA 部分

QDomCharacterData 表示 DOM 中的一个通用字符串

QDomComment 表示一个 XML 注释

QDomDocument 表示一个 XML 文档

QDomDocumentFragment QDomNodes 树,一般不是一个完整的 QDomDocument

QDomDocumentType 表示文档树中的 DTD

QDomElement 表示 DOM 树中的一个元素

QDomEntity 表明一个 XML 实体

QDomEntityReference 表明一个 XML 实体引用

QDomImplementation DOM 实现的功能的信息

QDomNamedNodeMap 包含一个节点集合,节点能够经过名字来访问

QDomNode 一个 DOM 树中全部节点的基类

QDomNodeList QDomNode 对象列表

QDomNotation 表明一个 XML 表示法

QDomProcessingInstruction 表明 XML 处理指令

QDomText 表示解析的 XML 文档中的文本数据

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

{

    QApplication a(argc, argv);

    MainWindow w;

    w.show();

    QDomDocument doc("mydocument");

    QFile file("/home/zz/Downloads/test.xml");

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

        return 0;

    if (!doc.setContent(&file)) {

        file.close();

        return 0;

    }

    file.close();

 

 

    // 打印出做为最外层元素的全部直接子元素的元素名称

    QDomElement docElem = doc.documentElement();

    // 这里,咱们在文档的末尾添加一个新元素

    QDomElement elem = doc.createElement("img");

    elem.setAttribute("src", "myimage.png");

    docElem.appendChild(elem);

    QDomNode n = docElem.firstChild();

    while(!n.isNull()) {

        QDomElement e = n.toElement(); // 尝试将节点转换为元素

        if(!e.isNull()) {

            cout << qPrintable(e.tagName())<< endl; // 节点真的是一个元素

            qDebug()<<e.text();

        }

        n = n.nextSibling();

    }

    QString str=doc.toString();

    w.ui->textBrowser->setText(str);

    return a.exec();

}

Introduce:

最经常使用的 DOM 类是 QDomNodeQDomDocumentQDomElement 和 QDomText

建立文档数据的多个函数,例如:createElement()createTextNode()createComment()createCDATASection()createProcessingInstruction()createAttribute() 和 createEntityReference()。这些函数中的一些具备支持命名空间的版本,即:createElementNS() 和 createAttributeNS()createDocumentFragment() 函数用于保存文档的各部分,这对于处理复杂文档颇有用。

能够根据 elementsByTagName() 或 elementsByTagNameNS() 获取具备特定标记的全部元素的列表。

void writeXML() {

    QDomDocument doc;//new create

    QDomProcessingInstruction xmlInstruction = doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"");

    QDomComment comment = doc.createComment(QString::fromLocal8Bit("This is a annotation"));

    QDomProcessingInstruction styleInstruction = doc.createProcessingInstruction("xml-stylesheet", "type=\"text/css\" href=\"style.css\"");

    doc.appendChild(xmlInstruction);  // 开始文档(XML 声明)

    doc.appendChild(comment);  // 注释

    doc.appendChild(styleInstruction);  // 处理指令

 

    // 根元素 <studentinfo>

    QDomElement root = doc.createElement("studentinfo");

    root.setAttribute("Version", "1.0");  // 属性

    doc.appendChild(root);

 

    // 元素

    QDomElement message = doc.createElement("message");

    root.appendChild(message);

 

    // 元素

    QDomElement name = doc.createElement(QString::fromLocal8Bit("name"));

    QDomElement num = doc.createElement(QString::fromLocal8Bit("num"));

    QDomElement instruction = doc.createElement(QString::fromLocal8Bit("instruction"));

    message.appendChild(name);

    message.appendChild(num);

    message.appendChild(instruction);

 

    // 元素的文本数据

    QDomText nameText = doc.createTextNode(QString::fromLocal8Bit("zylg"));

    QDomText numText = doc.createTextNode("1500710101");

    QDomText instructionText = doc.createTextNode(QString::fromLocal8Bit("Like to sleep"));

    name.appendChild(nameText);

    num.appendChild(numText);

    instruction.appendChild(instructionText);

 

    // 保存 XML 文件

    QString strFile("/home/zz/Downloads/test.xml");

    QFile file(strFile);

    if (file.open(QFile::WriteOnly | QFile::Text)) { // 只写模式打开文件

        QTextStream out(&file);

        doc.save(out, QDomNode::EncodingFromDocument);

        file.close();

    }

}

 

void readXML() {

    QDomDocument doc;

    QFile file("/home/zz/Downloads/test.xml");

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

        return;

    if (!doc.setContent(&file)) {

        file.close();

        return;

    }

    file.close();

 

    /**********根元素 <Blogs>**********/

    QDomElement root = doc.documentElement();

    qDebug() << root.tagName();

 

    if (root.hasAttribute("Version"))  // 属性

        qDebug() << root.attribute("Version");

 

    /**********根元素之上(XML 声明、注释等)**********/

    QDomNode node = root.previousSibling();

    while (!node.isNull()) {

        switch (node.nodeType()) {

        case QDomNode::ProcessingInstructionNode : {

            QDomProcessingInstruction instruction = node.toProcessingInstruction();

            qDebug() << instruction.target() << instruction.data();

            if (QString::compare(instruction.target(), "xml") == 0) { // 开始文档(XML 声明)

                // ...

            } else if (QString::compare(instruction.target(), "xml-stylesheet") == 0) { // 处理指令

                // ...

            }

            break;

        }

        case QDomNode::CommentNode : {

            QDomComment comment = node.toComment();

            qDebug() << comment.data();

            break;

        }

        default:

            break;

        }

        node = node.previousSibling();

    }

 

    /**********元素 <istudentinfo>**********/

    node = root.firstChild();  // 返回根节点的第一个子节点

    while (!node.isNull()) {

        if (node.isElement()) {

            QDomElement element = node.toElement();  // 尝试将节点转换为元素

            if (!element.isNull()) {  // 节点的确是一个元素

                qDebug() << element.tagName();

 

                /**********遍历元素 <name><num><introduce>**********/

                QDomNodeList list = element.childNodes();

                for (int i = 0; i < list.count(); i++) {

                    node = list.at(i);

                    if (node.isElement()) {

                        element = node.toElement();

                        qDebug() << element.tagName() << element.text();

                        if (QString::compare(element.tagName(), QStringLiteral("name")) == 0) {

                            // ...

                        } else if (QString::compare(element.tagName(), QStringLiteral("num")) == 0) {

                            // ...

                        } else if (QString::compare(element.tagName(), QStringLiteral("introduce")) == 0) {

                            // ...

                        }

                    }

                }

            }

        }

        node = node.nextSibling();

    }

}

 

 

Sax2

 

描述

QXmlAttributes用于向来是元素事件中传递属性

QXmlLocator用于获取事件的实际解析位置

QXmlNamespaceSupport用于为读取器实现命名空间支持

QXmlAttributes用于向来是元素事件中传递属性

QXmlLocator用于获取事件的实际解析位置

QXmlNamespaceSupport用于为读取器实现命名空间支持。

 

9.2. XML流(建议使用)

Qt 提供了两个新的类来读写 XMLQXmlStreamReader 和 QXmlStreamWriter

QXmlStreamReader xml;

...

while (!xml.atEnd()) {

    xml.readNext();

    ... // 作处理

}

if (xml.hasError()) {

    ... // 作错误处理

}

 

QXmlStreamWriter stream(&output);

stream.setAutoFormatting(true);

stream.writeStartDocument();

...

stream.writeStartElement("bookmark");

stream.writeAttribute("href", "http://qt-project.org/");

stream.writeTextElement("title", "Qt Project");

stream.writeEndElement(); // bookmark

...

stream.writeEndDocument();

 

Note:dtd

 

 

void writeXML() {

    QString strFile("/home/zz/Downloads/test.xml");

    QFile file(strFile);

    if (!file.open(QFile::WriteOnly | QFile::Text)) { // 只写模式打开文件

        qDebug() << QString("Cannot write file %1(%2).").arg(strFile).arg(file.errorString());

        return;

    }

//Start to write .xml file

    QXmlStreamWriter out(&file);

    out.setAutoFormatting(true);//format to auto set

    out.writeStartDocument("1.0",true);                     //start to write in .xml

        out.writeComment("This xml to introduce student info!");//it is annotation

        out.writeProcessingInstruction("xml-stylesheet type=\"text/css\" href=\"style.css\"");  // 处理指令

        out.writeDTD("<!DOCTYPE studentinfo ["

                     "<!ENTITY Copyright \"zylg\">"

                     "<!ELEMENT studentinfo (identity,interesting)>"

                     "<!ELEMENT identity      (name,age)>"

                     "<!ELEMENT name    (#PCDATA)>"

                     "<!ELEMENT age     (#PCDATA)>"

                     "<!ELEMENT interesting    (one,two)>"

                     "<!ELEMENT one    (#PCDATA)>"

                     "<!ELEMENT two    (#PCDATA)>"

                   "]>");

        out.writeStartElement("studentinfo");

        out.writeAttribute("Version","1.0");

            out.writeStartElement("identity");

                out.writeTextElement("name","zylg");

                out.writeTextElement("age","21");

                out.writeEntityReference("Copyright");

               // out.writeCharacters(">");

                out.writeCDATA("add introduce");

                out.writeEmptyElement("Empty");

            out.writeEndElement();

            out.writeStartElement("interesting");

                out.writeTextElement("one","Play baskball");

                out.writeTextElement("two","paly footballl");

            out.writeEndElement();

        out.writeEndElement();

    out.writeEndDocument();

    file.close();  // 关闭文件

}

 

 

void parseBlog(QXmlStreamReader &reader)

{

    while (!reader.atEnd())

    {

        if(reader.isStartElement())

        {

            if(reader.name().toString()=="identity")

            {

                qDebug()<<"identity element";

            }

            else if(reader.name().toString()=="interesting")

            {

                qDebug()<<"interesting element";

            }

        }

        else if(reader.name().toString()=="name")

        {

            QString str=reader.readElementText();

            if(str==NULL)qDebug()<<"have nill text";

            qDebug()<<"name:"<<str;

        }

        else if(reader.name().toString()=="age")

        {

            qDebug()<<"age:"<<reader.readElementText();

        }

        else if(reader.name().toString()=="one")

        {

            qDebug()<<"one:"<<reader.readElementText();

        }

        else if(reader.name().toString()=="two")

        {

            qDebug()<<"two:"<<reader.readElementText();

        }

        else if(reader.isEndElement())

        {

           if(reader.name().toString()=="identity")

           {

               qDebug()<<"</identity>";

           }

           else if(reader.name().toString()=="interesting")

           {

               qDebug()<<"</interesting>";

           }

            if(reader.name().toString()=="studentinfo")

            {

               qDebug()<<"</studentinfo>";

                break;

            }

 

        }

        reader.readNext();

    }

 

 

}

void readXML()

{

    QFile file("/home/zz/Downloads/test.xml");

    if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {  // 以只写模式打开文件

        QXmlStreamReader reader(&file);

 

        // 解析 XML,直到结束

        while (!reader.atEnd()) {

            // 读取下一个元素

            QXmlStreamReader::TokenType nType = reader.readNext();

 

            switch (nType) {

            case QXmlStreamReader::StartDocument:// 开始文档

            {

                QString strVersion = reader.documentVersion().toString();

                QString strEncoding = reader.documentEncoding().toString();

                bool bAlone = reader.isStandaloneDocument();

                qDebug() << QString::fromLocal8Bit("版本:%1  编码:%2  Standalone%3")

                            .arg(strVersion).arg(strEncoding).arg(bAlone) << "\r\n";

                break;

            }

            case QXmlStreamReader::Comment:

            {  // 注释

                qDebug() << QString::fromLocal8Bit("********** 注释 ********** ");

                QString strComment = reader.text().toString();

                qDebug() << strComment << "\r\n";

                break;

            }

            case QXmlStreamReader::ProcessingInstruction:

            {  // 处理指令

                qDebug() << QString::fromLocal8Bit("********** 处理指令 ********** ");

                QString strProcInstr = reader.processingInstructionData().toString();

                qDebug() << strProcInstr << "\r\n";

                break;

            }

            case QXmlStreamReader::DTD:

            {   // DTD

                qDebug() << QString::fromLocal8Bit("********** DTD ********** ");

                QString strDTD = reader.text().toString();

                QXmlStreamNotationDeclarations notationDeclarations = reader.notationDeclarations();  // 符号声明

                QXmlStreamEntityDeclarations entityDeclarations = reader.entityDeclarations();  // 实体声明

                // DTD 声明

                QString strDTDName = reader.dtdName().toString();

                QString strDTDPublicId = reader.dtdPublicId().toString();  // DTD 公开标识符

                QString strDTDSystemId = reader.dtdSystemId().toString();  // DTD 系统标识符

                qDebug() << QString::fromLocal8Bit("DTD : %1").arg(strDTD);

                qDebug() << QString::fromLocal8Bit("DTD 名称 : %1").arg(strDTDName);

                qDebug() << QString::fromLocal8Bit("DTD 公开标识符 : %1").arg(strDTDPublicId);

                qDebug() << QString::fromLocal8Bit("DTD 系统标识符 : %1").arg(strDTDSystemId);

                qDebug() << "\r\n";

 

                break;

            }

            case QXmlStreamReader::StartElement: {  // 开始元素

                QString strElementName = reader.name().toString();

                if (QString::compare(strElementName, "studentinfo") == 0) {  // 根元素

                    qDebug() << QString::fromLocal8Bit("********** 开始元素<studentinfo> ********** ");

                    QXmlStreamAttributes attributes = reader.attributes();

                    if (attributes.hasAttribute("Version")) {

                        QString strVersion = attributes.value("Version").toString();

                        qDebug() << QString::fromLocal8Bit("属性:Version(%1)").arg(strVersion);

                    }

 

                    parseBlog(reader);

                }

                break;

            }

            case QXmlStreamReader::EndDocument: {  // 结束文档

                qDebug() << QString::fromLocal8Bit("********** 结束文档 ********** ");

                break;

            }

            }

        }

 

        if (reader.hasError()) {  // 解析出错

            qDebug() << QString::fromLocal8Bit("错误信息:%1  行号:%2  列号:%3  字符位移:%4").arg(reader.errorString()).arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.characterOffset());

        }

 

        file.close();  // 关闭文件

    }

}

 

9.3. Json

JSON 中的值有 6 种基本数据类型:

· bool(QJsonValue::Bool)

· double(QJsonValue::Double)

· string(QJsonValue::String)

· array(QJsonValue::Array)

· object(QJsonValue::Object)

· null(QJsonValue::Null)

 

 

#include "ui_mainwindow.h"

#include<QJsonArray>

#include <QApplication>

#include "mainwindow.h"

#include<QFile>

#include<QString>

#include<QTextStream>

#include<QDebug>

#include<QJsonObject>

#include<QJsonDocument>

#include<QJsonParseError>

QString getjsonbyarray(QByteArray bytearray)

{

    QString strjson;

    QJsonParseError jsonError;

    QJsonDocument document=QJsonDocument::fromJson(bytearray,&jsonError);

    if(!(!document.isNull() && jsonError.error==QJsonParseError::NoError))exit(0);

     if (document.isObject()) // JSON 文档为对象

     {

        QJsonObject object = document.object();  // 转化为对象

        if (object.contains("Name"))strjson.append(object.value("Name").toString()+"\n");

        if (object.contains("Company"))strjson.append(object.value("Company").toString()+"\n");

        if (object.contains("From"))strjson.append(QString::number(object.value("From").toInt(),10)+"\n");

        if (object.contains("Version"))

        {

            QJsonValue value = object.value("Version");

            if (value.isArray())

            {  // Version  value 是数组

                QJsonArray array = value.toArray();

                int nSize = array.size();

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

                {

                    QJsonValue value = array.at(i);

                    strjson.append(QString::number(value.toDouble(),'f',3)+"\n");

                }

            }

        }

        if (object.contains("Page"))

         {

            QJsonValue value = object.value("Page");

             if (value.isObject())

            {

                QJsonObject obj = value.toObject();

                if (obj.contains("Home")) strjson.append(obj.value("Home").toString()+"\n");

                if (obj.contains("Download")) strjson.append(obj.value("Down

 

load").toString()+"\n");

                if (obj.contains("Developers"))strjson.append(obj.value("Developers").toString()+"\n");

            }

          }

 

    }

     return strjson;

}

QString createjson()

{// 构建 Json 数组 - Version

    QJsonArray versionArray;

    versionArray.append(4.8);

    versionArray.append(5.2);

    versionArray.append(5.7);

 

    // 构建 Json 对象 - Page

    QJsonObject pageObject;

    pageObject.insert("Home", "https://www.qt.io/");

    pageObject.insert("Download", "https://www.qt.io/download/");

    pageObject.insert("Developers", "https://www.qt.io/developers/");

 

    // 构建 Json 对象

    QJsonObject json;

    json.insert("Name", "Qt");

    json.insert("Company", "Digia");

    json.insert("From", 1991);

    json.insert("Version", QJsonValue(versionArray));

    json.insert("Page", QJsonValue(pageObject));

 

    // 构建 Json 文档

    QJsonDocument document;

    document.setObject(json);

    QFile savefile("/home/zz/save.json");

    if(!savefile.open(QFile::WriteOnly)){exit(0);}

    QTextStream out(&savefile);

    out<<document.toJson();

    savefile.close();

    QFile loadfile("/home/zz/save.json");

    if(!loadfile.open(QFile::ReadOnly))exit(0);

QByteArray byteArray=loadfile.readAll();

loadfile.close();

//    QByteArray byteArray = document.toJson(QJsonDocument::Compact);

    QString strJson(byteArray);

    return getjsonbyarray(byteArray);

//    return strJson;

}

 

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

{

    QApplication a(argc, argv);

    MainWindow w;

    w.resize(500,500);

    w.show();

  w.ui->textBrowser->setText(createjson());

 

    return a.exec();

}

 

 

9.4. Ini,注册表QSetting

contains() 判断一个指定的键是否存在

remove() 删除相关的键

allKeys() 获取全部键

clear() 删除全部键

value()进行值的读取

Setvalue()设置值

例子:

#include "mainwindow.h"

#include<QSettings>

#include <QApplication>

#include "ui_mainwindow.h"

#include<QString>

//#define HKEY_CURRENT_USER_QT  " HKEY_CURRENT_USER\\Software\\QtProject\\OrganizationDefaults\\Qt";

//#define INI_QT "G:\test\Digia";

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

{

    QApplication a(argc, argv);

    QCoreApplication::setOrganizationName(QString("Digia"));//组织名

    QCoreApplication::setApplicationName(QString("Qt"));//产品名

    QSettings settings(QSettings::IniFormat, QSettings::UserScope, QCoreApplication::organizationName(), QCoreApplication::applicationName());

                                                                                                                //NativeFormat=HKEY_CURRENT_USER\Software

                                                                                                                //IniFormat=C:\Users\zylg\AppData\Roaming

    settings.setValue("Name", "Qt Creator");//写入注册表

    settings.setValue("Version", 5);

    settings.setValue("zylg", 5);

    settings.setValue("l love the word", 5);

    settings.beginGroup("name1");

    settings.setValue("Name","zylg1");

    settings.setValue("number",15007);

        settings.beginGroup("son1");

        settings.setValue("路过","12345");

        settings.endGroup();

    settings.endGroup();

    settings.beginGroup("name2");

    settings.setValue("Name","zylg2");

    settings.setValue("number",15008);

    settings.remove("Name");//删除指定键,settings.clear()

    settings.endGroup();

 

    QString str=settings.value("Name").toString()+"\n";//读取注册表

    str.append(QString::number(settings.value("zylg").toFloat(),'2',0)+"\n");

    MainWindow w;

    settings.beginGroup("name1");

    settings.beginGroup("son1");

    str.append(QString::number(settings.value("路过").toDouble(),'1',0));

    settings.endGroup();

    settings.endGroup();

    QStringList strlist=settings.allKeys();

    w.show();

    w.ui->textBrowser->setText(str);

    w.ui->textBrowser->append("遍历输出key and value:");

    foreach (QString str, strlist )

    {

        w.ui->textBrowser->append(str+"="+settings.value(str).toString());

    }

    return a.exec();

 

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

10. 库和插件

10.1. 

第三方库包含:.h .lib(不一样编译平台不一样) .dll

在 Windows 中,MinGW 将输出 .a  .dllMSVC 将输出 .lib  .dll

在 Linux 中,MinGW 将输出 .so.so.1.so.1.0  .so.1.0.0 - .lib

 

只要在添加外部库文件的时候添加lib文件进去,而后在用的地方放进去.h文件,就能够编译成功。若是想要独立运行的时候,必须在exe文件的地方放入dll文件。

Windeployqt很强的打包文件windows下面使用

Linux下的ldd 能够找到依赖文件 cp过去就好

#ifndef SHAREDLIB_GLOBAL_H

#define SHAREDLIB_GLOBAL_H

 

#include <QtCore/qglobal.h>

 

#if defined(SHAREDLIB_LIBRARY)

#  define SHAREDLIBSHARED_EXPORT Q_DECL_EXPORT

#else

#  define SHAREDLIBSHARED_EXPORT Q_DECL_IMPORT

#endif

 

#endif // SHAREDLIB_GLOBAL_H

 

 

#ifndef SHAREDLIB_H

#define SHAREDLIB_H

 

#include "sharedlib_global.h"

SHAREDLIBSHARED_EXPORT int sub(int x,int y);

 

class SHAREDLIBSHARED_EXPORT SharedLib

{

 

public:

    SharedLib();

    int add(int x,int y);

};

 

#endif // SHAREDLIB_H

 

运行时加载共享库

QLibrary加载的流程(不用lib和.h文件了,一个dll搞定)

.构造QLibrary实例

.setFileName()指定共享库的文件名

.load()动态加载共享库,isload()判断是否加载

.resolve()解析共享库的符号

.unload()卸载共享库

#include <QCoreApplication>

#include <QLibrary>

#include <QDebug>

 

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

{

    QCoreApplication a(argc, argv);

 

    QLibrary lib("SharedLib"); // SharedLibd.dll 与可执行程序位于同一目录

 

    if (lib.load())  // 加载共享库

    {

        typedef int (*Fun)(int, int); // 解析符号,fun指向函数的指针

        Fun sub = (Fun) lib.resolve("subt");//解析函数名,把就必须为c函数

        if (sub)

        {

            int result = sub(5, 2);

            qDebug() << result;

        } else

        {

            qDebug() << "Can not resolve subtract";

        }

        lib.unload(); // 卸载共享库

    } else

    {

        qDebug() << lib.errorString();

    }

    return a.exec();

}

windows能够运行,可是linux不知道为啥,弄不出来,暂留

加载静态库和动态库时同样的

 

加载静态库,在打包程序时就不用包括dll文件了

 

 

10.2. 插件

修改自己插件

基类

目录

Qt 模块

大小写敏感性

QAccessibleBridgePlugin

accessiblebridge

Qt GUI

区分大小写

QImageIOPlugin

imageformats

Qt GUI

区分大小写

QPictureFormatPlugin (obsolete)

pictureformats

Qt GUI

区分大小写

QAudioSystemPlugin

audio

Qt Multimedia

区分大小写

QDeclarativeVideoBackendFactoryInterface

video/declarativevideobackend

Qt Multimedia

区分大小写

QGstBufferPoolPlugin

video/bufferpool

Qt Multimedia

区分大小写

QMediaPlaylistIOPlugin

playlistformats

Qt Multimedia

区分大小写

QMediaResourcePolicyPlugin

resourcepolicy

Qt Multimedia

区分大小写

QMediaServiceProviderPlugin

mediaservice

Qt Multimedia

区分大小写

QSGVideoNodeFactoryPlugin

video/videonode

Qt Multimedia

区分大小写

QBearerEnginePlugin

bearer

Qt Network

区分大小写

QPlatformInputContextPlugin

platforminputcontexts

Qt Platform Abstraction

区分大小写

QPlatformIntegrationPlugin

platforms

Qt Platform Abstraction

区分大小写

QPlatformThemePlugin

platformthemes

Qt Platform Abstraction

区分大小写

QGeoPositionInfoSourceFactory

position

Qt Positioning

区分大小写

QPlatformPrinterSupportPlugin

printsupport

Qt Print Support

区分大小写

QSGContextPlugin

scenegraph

Qt Quick

区分大小写

QScriptExtensionPlugin

script

Qt Script

区分大小写

QSensorGesturePluginInterface

sensorgestures

Qt Sensors

区分大小写

QSensorPluginInterface

sensors

Qt Sensors

区分大小写

QSqlDriverPlugin

sqldrivers

Qt SQL

区分大小写

QIconEnginePlugin

iconengines

Qt SVG

区分大小写

QAccessiblePlugin

accessible

Qt Widgets

区分大小写

QStylePlugin

styles

Qt Widgets

区分大小写

 

.pro file

QT += widgets

TEMPLATE = lib

CONFIG += plugin

TARGET = stylePlugin

 

HEADERS += \

    simple_style.h \

    style_plugin.h

 

OTHER_FILES += simple.json

 

win32 {

    CONFIG(debug, release|debug):DESTDIR = ../debug/styles/

    CONFIG(release, release|debug):DESTDIR = ../release/styles/

} else {

    DESTDIR = ../styles/

}

这个东西很重要

 

 

.h file

#ifndef SIMPLE_STYLE_H

#define SIMPLE_STYLE_H

 

#include <QProxyStyle>

#include<QDebug>

class SimpleStyle : public QProxyStyle

{

    Q_OBJECT

 

public:

    SimpleStyle() {}

 

    void polish(QPalette &palette) override

    {

        palette.setBrush(QPalette::ButtonText, Qt::red);

    }

};

 

#endif // SIMPLE_STYLE_H

 

 

#ifndef STYLE_PLUGIN_H

#define STYLE_PLUGIN_H

 

#include <QStylePlugin>

#include "simple_style.h"

 

class StylePlugin : public QStylePlugin

{

    Q_OBJECT

    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "simple.json")

 

public:

    StylePlugin() {}

 

    QStyle *create(const QString &key) override

    {

        if (key.toLower() == "mystyle")

            return new SimpleStyle();

 

        return Q_NULLPTR;

    }

};

 

#endif // STYLE_PLUGIN_H

 

 

.json

{

    "Keys": ["mystyle"]

}

 

应用程序插件扩展

在这里添加了类和json两个东西,接口处标红标记,此外在pro文件的DESTDIR两个文件设置同样,person.h文件复制到测试的文件夹

#-------------------------------------------------

#

# mylife.pro

#

#-------------------------------------------------

 

QT       -= gui

QT  +=core

 

TARGET = mlife

TEMPLATE = lib

CONFIG +=plugin

 

DEFINES += MYLIFE_LIBRARY

 

SOURCES += mylife.cpp \

 

 

HEADERS += mylife.h\

                         person.h

 

DESTDIR =../plugins/

 

DISTFILES += \

zylg.json

 

//mylife.h

#ifndef MYLIFE_H

#define MYLIFE_H

#include"person.h"

#include<QDebug>

#include<QObject>

class  Mylife:public  QObject,person

{

    Q_OBJECT

    Q_INTERFACES(person)

     Q_PLUGIN_METADATA(IID myiid FILE "zylg.json")

 

public:

    virtual   void eat() Q_DECL_OVERRIDE;

    virtual void sleep() Q_DECL_OVERRIDE;

   virtual void work() Q_DECL_OVERRIDE;

};

 

#endif // MYLIFE_H

#ifndef PERSON_H

#define PERSON_H

 

#include <QtPlugin>

#include <QString>

 

class person

{

public:

    virtual  void eat()=0;

     virtual  void sleep()=0;

     virtual  void work()=0;

};

#define myiid "org.qt-project.Qt.Examples.person"

Q_DECLARE_INTERFACE(person, myiid)

#endif // PERSON_H

{

    "author" : "zylg",

    "date" : "2018/05/18",

    "name" : "personPlugin",

    "version" : "1.0.0",

    "dependencies" : []

}

 

 

 

#include <QCoreApplication>

#include <QPluginLoader>

#include <QDir>

#include <QtDebug>

#include <QJsonObject>

#include <QJsonArray>

#include  "person.h"

 

void loadPlugin()

{

    // 进入插件目录

    QDir pluginsDir(qApp->applicationDirPath());

    pluginsDir.cd("plugins");

    qDebug()<<pluginsDir.path();

    // 查找目录中的全部插件

    foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {

        qDebug()<<fileName;

        QPluginLoader loader(pluginsDir.absoluteFilePath(fileName));

        // 返回插件的根组件对象

        QObject *pPlugin = loader.instance();

        if (pPlugin != Q_NULLPTR) {

 

            // 获取元数据(名称、版本、依赖)

            QJsonObject json = loader.metaData().value("MetaData").toObject();

            qDebug() << "********** MetaData **********";

            qDebug() << json.value("author").toVariant();

            qDebug() << json.value("date").toVariant();

            qDebug() << json.value("name").toVariant();

            qDebug() << json.value("version").toVariant();

            qDebug() << json.value("dependencies").toArray().toVariantList();

 

            // 访问感兴趣的接口

            person *pPerson = qobject_cast<person *>(pPlugin);

            if (pPerson != Q_NULLPTR) {

                qDebug() << "********** IPerson **********";

                pPerson->eat();

            } else {

                qWarning() << "qobject_cast falied";

            }

        }

    }

}

 

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

{

    QCoreApplication a(argc, argv);

 

    loadPlugin();

 

    return a.exec();

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

11. 绘图系统

像素的绘制在该点的右下角,均可执行scale() rotate()  translate()

基本绘制

文本显示不全能够由QtextOption来控制

QTextOption option(Qt::AlignLeft | Qt::AlignVCenter)

option.setWrapMode(QTextOption::WordWrap); 

painter.drawText(rect()QStringLiteral("这世界很美好")option); 

void MainWindow::paintEvent(QPaintEvent *event)

{

    QFont font;

    font.setItalic(true);

    font.setBold(true);

    font.setPointSize(20);

    QPainter painter(this);

    painter.setFont(font);

    painter.setPen(Qt::red);

    painter.drawText(QRect(0,0,100,100),Qt::AlignCenter,"zylg");

    painter.setPen(QPen(Qt::blue,6));

painter.drawLine(QPointF(0,height()),QPoint(width()/2,height()/2));

    painter.drawEllipse(QPointF(210, 140), 40, 40)

    painter.setBrush(QColor(0,255,0));

    painter.drawRect(50,100,100,100);

 

 

}

 

 

渐变

 

QLinearGradient 显示从起点到终点的渐变。

void MainWindow::paintEvent(QPaintEvent *event)

{

    QPainter painter(this);

    // 设置渐变色

    QLinearGradient linear(QPointF((width()-200/2), (height()-200)/2),QPointF((width()-200/2)/2,180));

    linear.setColorAt(0, Qt::green);

    linear.setColorAt(1,Qt::red);

    // 设置画刷填充

//    linear.setSpread(QGradient::PadSpread);

  linear.setSpread(QGradient::ReflectSpread);

//    linear.setSpread(QGradient::RepeatSpread);

    painter.setBrush(linear);

    // 绘制椭圆

    painter.drawRect(QRect((width()-200)/2, height()/2-100, 180, 180));

}

 

 

QRadialGradient 类以圆心为中心显示渐变。(cx, cy) 是中点,半径(radius)是以中点为圆心的圆的半径,(fx, fy) 是渐变的起点。

void MainWindow::paintEvent(QPaintEvent *event)

{

    QPainter painter(this);

    // 设置渐变色

    QRadialGradient linear(QPointF((width()/2), (height())/2),30,QPointF(0,180));

    linear.setColorAt(0, Qt::green);

    linear.setColorAt(1,Qt::red);

    // 设置画刷填充

//    linear.setSpread(QGradient::PadSpread);

//    linear.setSpread(QGradient::ReflectSpread);

    linear.setSpread(QGradient::RepeatSpread);

    painter.setBrush(linear);

    // 绘制椭圆

    painter.drawRect(QRect((width()-200)/2, height()/2-100, 180, 180));

 

 

}

 

QConicalGradient 在 (cx, cy) 坐标上以角度 (angle) 为中心显示渐变

void MainWindow::paintEvent(QPaintEvent *event)

{

    QPainter painter(this);

    // 设置渐变色

    QConicalGradient linear(QPointF((width()/2),height()/2),45);

    linear.setColorAt(0, Qt::green);

    linear.setColorAt(1,Qt::red);

    // 设置画刷填充

    linear.setSpread(QGradient::PadSpread);

//    linear.setSpread(QGradient::ReflectSpread);

    linear.setSpread(QGradient::RepeatSpread);

//    painter.setBrush(linear);

    // 绘制椭圆

    painter.drawRect(QRect((width()-200)/2, height()/2-100, 180, 180));

 

 

}

 

转换

translate(qreal dx, qreal dy):平移 对坐标系沿着 轴移动 dx、沿 轴移动 dy

scale(qreal sx, qreal sy):缩放 经过水平的 sx 和垂直的 sy 缩放坐标系

rotate(qreal angle, Qt::Axis axis = Qt::ZAxis):旋转 对指定的轴用给定的角度反时针旋转坐标系统

shear(qreal sh, qreal sv):扭曲 经过水平的 sh 和垂直的 sv 扭曲坐标系

reset():重置为单位矩阵

void MainWindow::paintEvent(QPaintEvent *event)

{

    QPainter painter(this);

    painter.drawPixmap(QRect(0, 0, 160, 160),QPixmap("../wangzai.jpg"));

    QTransform transform;

    transform.translate(120,20);

    painter.setTransform(transform);

    painter.drawPixmap(QRect(0, 0, 160, 160),QPixmap("../wangzai.jpg"));

    transform.reset();

    transform.rotate(45,Qt::XAxis);

    painter.setTransform(transform);

    painter.drawPixmap(QRect(280, 0, 160, 160),QPixmap("../wangzai.jpg"));

    transform.reset();

    transform.shear(0.5,0);

    transform.rotate(45,Qt::YAxis);

    painter.setTransform(transform);

    painter.drawPixmap(QRect(0, 180, 160, 160),QPixmap("../wangzai.jpg"));

    transform.reset();

    transform.scale(0.5,0.5);

    transform.rotate(45,Qt::ZAxis);

    painter.setTransform(transform);

    painter.drawPixmap(QRect(420, -60, 160, 160),QPixmap("../wangzai.jpg"));

}

 

 

QPainterPath

里面的moveTo()    cubicTo() lineTo()最基本的构成元素,能够组合为其余的东西

QPainterPathStroker

· setWidth():宽度

· setCapStyle():端点风格

· setJoinStyle():链接样式

· setDashPattern():虚线图案

 

 

void MainWindow::paintEvent(QPaintEvent *event)

{

    QPainterPath path;

    path.addRect((width()-240)/2, (height()-240)/2, 240, 240);

 

    path.moveTo((width()-400)/2, (height()-400)/2);

    path.cubicTo(449, 50,  250, 250,  449, 449);

    path.cubicTo(50, 449,  250, 250,  50, 50);

 

    QPainter painter(this);

    painter.fillRect((width()-400)/2, (height()-400)/2,400,400, Qt::white);

    painter.setPen(QPen(QColor(79, 106, 25), 1, Qt::SolidLine,

                        Qt::FlatCap, Qt::MiterJoin));

    painter.setBrush(QColor(122, 163, 39));

 

    painter.drawPath(path);

}

 

 

void MainWindow::paintEvent(QPaintEvent *event)

{

    Q_UNUSED(event);

 

        QPainter painter(this);

        painter.setRenderHint(QPainter::Antialiasing, true);

 

        // 矩形 300 * 200

        QRectF rect(50, 50, 300, 200);

        QPainterPath path;

        path.addRect(rect);

 

        // 绘制原始路径

        painter.drawPath(path);

       // 生成可填充的轮廓

        QPainterPathStroker stroker;

        stroker.setCapStyle(Qt::RoundCap);  // 端点风格

        stroker.setJoinStyle(Qt::RoundJoin);  // 链接样式

        stroker.setDashPattern(Qt::DashLine);  // 虚线图案

        stroker.setWidth(10);  // 宽度

 

        // 绘制轮廓

        painter.setPen(Qt::green);

        painter.fillPath(stroker.createStroke(path),QBrush(Qt::yellow));

}

 

 

 

圆形:

void drawimage(QPainter *painter,int radius,int startAngle,QRgb color)

{

    // 渐变色

    QRadialGradient gradient(0, 0, radius);

    gradient.setColorAt(0, Qt::white);

    gradient.setColorAt(1.0, color);

    painter->setBrush(gradient);

    QRectF rect(-radius, -radius, radius << 1, radius << 1);

    QPainterPath path;

    path.arcTo(rect, startAngle, 45);

    painter->setPen(Qt::NoPen);

    painter->drawPath(path);

}

void MainWindow::paintEvent(QPaintEvent *event)

{

    QPainter painter(this);

    painter.setRenderHint(QPainter::Antialiasing, true);

    int radius = 150;

    painter.translate(width() >> 1, height() >> 1);;

    drawimage(&painter,radius,0,qRgb(200,200,0));

    drawimage(&painter,radius,45,qRgb(200,0,200));

    drawimage(&painter,radius,90,qRgb(200,0,0));

    drawimage(&painter,radius,135,qRgb(0,200,0));

    drawimage(&painter,radius,180,qRgb(150,200,0));

    drawimage(&painter,radius,225,qRgb(150,0,0));

    drawimage(&painter,radius,270,qRgb(200,100,0));

    drawimage(&painter,radius,315,qRgb(200,20,0));

}

 

void drawimage(QPainter *painter,int radius,int startAngle,QRgb color)

{

    // 渐变色

    QRadialGradient gradient(0, 0, radius);

    gradient.setColorAt(0, Qt::white);

    gradient.setColorAt(1.0, color);

    painter->setBrush(gradient);

    QRectF rect(-radius, -radius, radius << 1, radius << 1);

    QPainterPath path;

    path.arcTo(rect, startAngle, 45);

    QPainterPath subpath;

    subpath.addEllipse(rect.adjusted(30,30,-30,-30));

    path-=subpath;

    painter->setPen(Qt::NoPen);

    painter->drawPath(path);

}

 

 

void drawimage(QPainter *painter,int radius,int startAngle,QRgb color)

{

    // 渐变色

    QRadialGradient gradient(0, 0, radius);

    gradient.setColorAt(0, Qt::white);

    gradient.setColorAt(1.0, color);

    painter->setBrush(gradient);

    QRectF rect(-radius, -radius, radius << 1, radius << 1);

    QPainterPath path;

    path.arcTo(rect, startAngle, 45);

    QPainterPath subpath;

    subpath.addEllipse(rect.adjusted(30,30,-30,-30));

    path-=subpath;

    QFont font;

    font.setPointSize(15);

    path.addText(path.pointAtPercent(0.5),font,"i love the world");

    painter->setPen(Qt::NoPen);

    painter->drawPath(path);

}

 

 

 

 

 

void MainWindow::paintEvent(QPaintEvent *event)

{

    QPainter painter(this);

    painter.setRenderHint(QPainter::Antialiasing, true);

    painter.translate(width()/2,height()/2);

    painter.rotate(ang);

    painter.translate(0-width()/2,0-height()/2);

    int radius = 150;

painter.translate(width() >> 1, height() >> 1);;

drawimage(&painter,radius,0,qRgb(200,200,0));

drawimage(&painter,radius,45,qRgb(200,0,200));

drawimage(&painter,radius,90,qRgb(200,0,0));

drawimage(&painter,radius,135,qRgb(0,200,0));

drawimage(&painter,radius,180,qRgb(150,200,0));

drawimage(&painter,radius,225,qRgb(150,0,0));

drawimage(&painter,radius,270,qRgb(200,100,0));

drawimage(&painter,radius,315,qRgb(200,20,0));

}

放一个定时器改变ang的大小便可

 

 

#include "mainwindow.h"

#include<QPainter>

#include<QTime>

#include<QTimer>

#include<QColor>

#include<QFont>

#include<qmath.h>

#include<QTransform>

MainWindow::MainWindow(QWidget *parent)

    : QWidget(parent)

{

 

    setWindowTitle("zylg");

    QTimer *pTimer = new QTimer(this);

    pTimer->setInterval(1);

    connect(pTimer, SIGNAL(timeout()),this,SLOT(update()));

    pTimer->start();

}

 

MainWindow::~MainWindow()

{

 

}

QRectF MainWindow::textRectF(double radius, int pointSize, double angle)

{

    QRectF rectF;

    rectF.setX(radius*qCos(angle*M_PI/180.0) - pointSize*2);

    rectF.setY(radius*qSin(angle*M_PI/180.0) - pointSize/2.0);

    rectF.setWidth(pointSize*4);

    rectF.setHeight(pointSize);

    return rectF;

}

void MainWindow::paintEvent(QPaintEvent *event)

{

    Q_UNUSED(event);

 

        // 时针、分针、秒针位置 - 多边形

        static const QPoint hourHand[3] =

        {

            QPoint(7, 8),

            QPoint(-7, 8),

            QPoint(0, -30)

        };

        static const QPoint minuteHand[3] =

        {

            QPoint(7, 8),

            QPoint(-7, 8),

            QPoint(0, -65)

        };

 

        static const QPoint secondHand[3] =

        {

            QPoint(7, 8),

            QPoint(-7, 8),

            QPoint(0, -80)

        };

 

        // 时针、分针、秒针颜色

        QColor hourColor(200, 100, 0, 200);

        QColor minuteColor(0, 227, 127, 150);

        QColor secondColor(0, 250, 230, 150);

 

        int side = qMin(width(), height());

        QTime time = QTime::currentTime();

 

        QPainter painter(this);

        painter.setRenderHint(QPainter::Antialiasing);

        // 平移坐标系原点至中心点

        painter.translate(width() / 2, height() / 2);

        // 缩放

        painter.scale(side / 200.0, side / 200.0);

 

        // 绘制时针

        painter.setPen(Qt::NoPen);

        painter.setBrush(hourColor);

 

        painter.save();

        // 每圈360° = 12h 即:旋转角度 = 小时数 * 30°

        painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));

        painter.drawConvexPolygon(hourHand, 3);

        painter.restore();

 

        painter.setPen(hourColor);

 

        // 绘制小时线 360 / 12 = 30度)

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

        {

            painter.drawLine(88, 0, 96, 0);

            painter.rotate(30.0);

        }

 

        int radius = 100;

        QFont font = painter.font();

        font.setBold(true);

        painter.setFont(font);

        int pointSize = font.pointSize();

 

        // 绘制小时文本

        int nHour = 0;

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

        {

            nHour = i+3 ;

            if (nHour > 12)

                nHour -= 12;

            painter.drawText(textRectF(radius*0.8, pointSize, i * 30), Qt::AlignCenter, QString::number(nHour));

        }

 

        // 绘制分针

        painter.setPen(Qt::NoPen);

        painter.setBrush(minuteColor);

 

        painter.save();

        // 每圈360° = 60m 即:旋转角度 = 分钟数 * 

        painter.rotate(6.0 * (time.minute() + time.second() / 60.0));

        painter.drawConvexPolygon(minuteHand, 3);

        painter.restore();

 

        painter.setPen(minuteColor);

 

        // 绘制分钟线 360 / 60 = 6度)

        for (int j = 0; j < 60; ++j)

        {

            if ((j % 5) != 0)

                painter.drawLine(92, 0, 96, 0);

            painter.rotate(6.0);

        }

 

        // 绘制秒针

        painter.setPen(Qt::NoPen);

        painter.setBrush(secondColor);

 

        painter.save();

        // 每圈360° = 60s 即:旋转角度 = 秒数 * 

        painter.rotate(6.0 * time.second());

        painter.drawConvexPolygon(secondHand, 3);

        painter.restore();

}

 

 

 

 

Imagewrite and imagereader

公共函数

void setFileName(const QString & fileName) 

void setFormat(const QByteArray & format) 

void setText(const QString & key, const QString & text) 

bool supportsOption(QImageIOHandler::ImageOption option) const //png格式容许嵌入文字

void setQuality(int quality) 设置图像格式的质量。

#include "mainwindow.h"

#include<QImage>

#include<QImageWriter>

#include<QDebug>

#include <QApplication>

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

{

    QApplication a(argc, argv);

    QImage img("/home/zz/qt/wangzaicd ../");

   QImageWriter write("wangzaiLogo.jpeg","jpeg");

   if(write.supportsOption(QImageIOHandler::Description))

   {

       write.setText("AUthor","zylg");

       write.setText("date","2018/5/23");

   }

   write.setQuality(100);

   if(write.canWrite())write.write(img);

   else qDebug()<<write.errorString();

//    MainWindow w;

//    w.resize(500,500);

//    w.show();

    return a.exec();

}

 

 

 

QImageReader

void  setFileName(const QString &filename)

void setFormat(const QByteArray & format) 

QStringList textKeys() const //返回此图片全部的keys

QString text(const QString & key)// const返回对应的key

bool supportsOption(QImageIOHandler::ImageOption option) const 

void setQuality(int quality) 

bool supportsAnimation() const //是否支持动画

int loopCount() const //动画的循环次数

int nextImageDelay() const //动画下一帧等待的秒数

int imageCount() const //动画图像的总数

int currentImageNumber() const //当前帧的序号

bool jumpToImage(int imageNumber) 跳到指定的序号图像

bool jumpToNextImage() 

bool canRead() const 

bool read(QImage * image) 

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

{

    QApplication a(argc, argv);

    QImageReader reader;

    reader.setFileName("../painter001/wangzaiLogo.jpeg");

    if(reader.canRead())

    {

        QStringList keys=reader.textKeys();

        QString strvalue("");

        foreach (QString str, keys)

        {

            strvalue=reader.text(str);

            qDebug()<<QString("Key %1  value %2").arg(str).arg(strvalue);

        }

    }

    else

    {

        qDebug()<<reader.errorString();

    }

    return a.exec();

}

 

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

{

    QApplication a(argc, argv);

    QImageReader reader;

    reader.setFileName("../1");

    if (reader.supportsAnimation())

    {

        // 动画循环的次数

        int nLoopCount = reader.loopCount();

        qDebug() << QString("Loop Count : %1").arg(nLoopCount);

 

        int nCount = reader.imageCount();

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

        {

            // 跳到顺序号为i的图像

            bool ret = reader.jumpToImage(i);

            if (reader.canRead())

            {

                // 读取图像

                QImage image = reader.read();

 

                // 保存图像

                image.save(QString("Loading%1.jpeg").arg(i + 1));

 

                // 下一帧动画等待的毫秒数

                int nDelay = reader.nextImageDelay();

                qDebug() << QString("Number %1 Delay : %2").arg(i + 2).arg(nDelay);

            }

            else

            {

                // 获取错误信息

                QImageReader::ImageReaderError error = reader.error();

                QString strError = reader.errorString();

                qDebug() << "Last Error : " << strError;

            }

        }

    }

    return a.exec();

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

12. 图形视图框架

1.场景:

QGraphicsScene提供了图形视图场景,时item的容器

· 提供一个快速的接口,用于管理大量图元

· 向每一个图元传递事件

· 管理图元的状态,如:选中、焦点处理

· 提供未进行坐标转换的渲染功能,主要用于打印

QGraphicsScene::addItem()将图元添加到场景

QGraphicsScene::items()函数及其重载函数能够返回全部图元

QGraphicsScene::itemAt()返回在特定点上最上面的图元,最后返回的时最下层的

QGraphicsScene::setFocusItem()或QGraphicsItem::setFocus()为一个图元设置焦点,或经过QGraphicsScene::focusItem()获取当前的焦点图元。

QGraphicsScene::render()和QGraphicsView::render()

 

视图:

图元:

· 鼠标按下、移动、释放和双击事件,以及鼠标悬浮事件、滚轮事件和上下文菜单事件。

· 键盘输入焦点和键盘事件。

· 拖放。

· 分组:经过父子关系,或QGraphicsItemGroup。

· 碰撞检测。

打印:

QGraphicsScene scene; 

scene.addRect(QRectF(00100200), QPen(Qt::black), QBrush(Qt::green));

 QPixmap pixmap; 

QPainter painter(&pixmap);

 painter.setRenderHint(QPainter::Antialiasing); 

scene.render(&painter);

 painter.end(); 

pixmap.save("scene.png");

 

常见的图元:

· QGraphicsSimpleTextItem:提供了一个简单的文本标签项

· QGraphicsTextItem:提供了一个格式化的文本项

· QGraphicsLineItem:提供了一个直线项

· QGraphicsPixmapItem:提供了一个图像项

· QGraphicsRectItem:提供了一个矩形项

· QGraphicsEllipseItem:提供了一个椭圆项

· QGraphicsPathItem:提供了一个路径项

· QGraphicsPolygonItem:提供了一个多边形项

文本

QGraphicsTextItem格式化文本项

 QGraphicsTextItem *textitem=new QGraphicsTextItem();

    QString strHTML = QString("<html> \

                                   <head> \

                                   <style> \

                                   font{color:white;} #f{font-size:18px; color: #00A0E6;} \

                                   </style> \

                                   </head> \

                                   <body>\

                                   <font>%1</font><font id=\"f\">%2</font> \

                                   <br/><br/> \

                                   <a href=\"www.baidu.com\"><img src=\"../wangzai1.jpg\" width=\"100\" height=\"100\"> <\a>\

                                   </body> \

                                   </html>").arg("I am a ").arg("Qter");

    textitem->setHtml(strHTML);

    textitem->setOpenExternalLinks(true);

    textitem->setTextInteractionFlags(Qt::TextBrowserInteraction);

    connect(textitem, &QGraphicsTextItem::linkActivated, [=](QString link) {

                QDesktopServices::openUrl(QUrl(link));

    });

    QFont font=textitem->font();

    font.setPixelSize(20);

    font.setUnderline(true);

    textitem->setFont(font);

    //add text to scene

    QGraphicsScene *scene=new QGraphicsScene();

    scene->addItem(textitem);

    //display scene on view

    QGraphicsView *view=new QGraphicsView();

    view->setScene(scene);

    view->setStyleSheet("border:none;background:transparent;");

    view->show();

 

 

QGraphicsSimpleTextItem

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

{

    QApplication a(argc, argv);

    QGraphicsSimpleTextItem *textitem=new QGraphicsSimpleTextItem();

    textitem->setText("my name is zylg");

    QFont font=textitem->font();

    font.setPixelSize(20);

    font.setUnderline(true);

    textitem->setFont(font);

    textitem->setBrush(Qt::green);

    //add text to scene

    QGraphicsScene *scene=new QGraphicsScene();

    scene->addItem(textitem);

    //display scene on view

    QGraphicsView *view=new QGraphicsView();

    view->setScene(scene);

    view->setStyleSheet("border:none;background:transparent;");

    view->show();

    return a.exec();

}

 

 textitem->setPlainText("my name is zykg");

    QFont font=textitem->font();

    font.setPixelSize(20);

    textitem->setDefaultTextColor(Qt::green);

    font.setUnderline(true);

    textitem->setFont(font);

    textitem->setTextInteractionFlags(Qt::TextEditorInteraction);//can edit text

 

 

直线:

    QGraphicsLineItem *line = new QGraphicsLineItem();

     // 设置直线位于 (x1, y1)  (x2, y2)之间

    line->setLine(QLineF(0, 0, 100, 100));

 

图像:

// 定义一个 item 

QGraphicsPixmapItem *pItem = new QGraphicsPixmapItem(); 

QPixmap image(":/Images/logo"); 

pItem->setPixmap(image.scaled(5050));

矩形:

// 定义一个 item

QGraphicsRectItem  *pItem = new QGraphicsRectItem();

// 矩形区域 起点:(50, 50) 宽:100 高:100

pItem->setRect(QRectF(50, 50, 100, 100));

圆:

path:

pItem->setPath(starPath);

多边形:

// 绘制多边形

QPolygonF polygon;

polygon << QPointF(200.0, 120.0) << QPointF(230.0, 130.0)

        << QPointF(260.0, 180.0) << QPointF(200.0, 200.0);

pItem->setPolygon(polygon);

 

嵌入Qwidget(状态同步)

QGraphicsScene scene;

 QGraphicsProxyWidget *pProxy = scene.addWidget(pGroupBox); 

QGraphicsView view(&scene); 

view.show();

 

QGraphicsWidget *pWidget = new QGraphicsWidget();

pWidget->setLayout(pLayout);

 

//  item 添加至场景中

pScene->addItem(pWidget);

 

// 为视图设置场景

QGraphicsView *pView = new QGraphicsView();

pView->setScene(pScene);

pView->show();

 

QGraphicsScene管理QGraphicsItem(单击/选择/移动/缩放/删除)

操做细节主要包括:

· 选择:点击左键、按 Shift 键能够单选,按下 Ctrl 可进行多选。

· 添加:点击左键

· 删除:点击右键,删除鼠标下的 item;当按下 Ctrl 选择多个 items 时,按下 Backspace 键,将选中的所有删除。

· 移动:点击左键,选择 item,而后移动鼠标;当按下 Ctrl 选择多个 items 时,能够移动选中的 items。

· 缩放:按 Alt 键,而后鼠标拖拽 item 的边界。

 

#ifndef CUSTOM_ITEM_H

#define CUSTOM_ITEM_H

 

#include <QGraphicsRectItem>

#include <QGraphicsScene>

 

//QGraphicsScene管理QGraphicsItem(单击/选择/移动/缩放/删除)

// 自定义 Item

class CustomItem : public QGraphicsRectItem

{

public:

    explicit CustomItem(QGraphicsItem *parent = 0);

protected:

    // Shift+左键:进行选择  Alt:准备缩放

    void mousePressEvent(QGraphicsSceneMouseEvent *event);

    // Alt+拖拽:进行缩放  移动

    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);

    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);

    // 使item可以使用qgraphicsitem_cast

    int type() const;

private:

    QPointF m_centerPointF;

    bool m_bResizing;

};

 

// 自定义 Scene

class CustomScene : public QGraphicsScene

{

protected:

    // 左键:添加item  右键:移除item

    void mousePressEvent(QGraphicsSceneMouseEvent *event);

    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);

    // Backspace键移除item

    void keyPressEvent(QKeyEvent *event);

};

 

#endif // CUSTOM_ITEM_H

 

#include "customitem.h"

#include <QKeyEvent>

#include <QGraphicsSceneMouseEvent>

#include <QDebug>

 

// 自定义 Item

CustomItem::CustomItem(QGraphicsItem *parent)

    : QGraphicsRectItem(parent)

{

    // 画笔 - 边框色

    QPen p = pen();

    p.setWidth(2);

    p.setColor(QColor(0, 160, 230));

 

    setPen(p);

    // 画刷 - 背景色

    setBrush(QColor(247, 160, 57));

 

    // 可选择、可移动

    setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable);

}

 

void CustomItem::mousePressEvent(QGraphicsSceneMouseEvent *event)

{

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

    {

        if (event->modifiers() == Qt::ShiftModifier)

        {

            qDebug() << "Custom item left clicked with shift key.";

            // 选中 item

            setSelected(true);

        }

        else if (event->modifiers() == Qt::AltModifier)

        {

            qDebug() << "Custom item left clicked with alt key.";

            // 重置 item 大小

            double radius = boundingRect().width() / 2.0;

            QPointF topLeft = boundingRect().topLeft();

            m_centerPointF = QPointF(topLeft.x() + pos().x() + radius, topLeft.y() + pos().y() + radius);

            QPointF pos = event->scenePos();

            qDebug() << boundingRect() << radius << this->pos() << pos << event->pos();

            double dist = sqrt(pow(m_centerPointF.x()-pos.x(), 2) + pow(m_centerPointF.y()-pos.y(), 2));

            if (dist / radius > 0.8)

            {

                qDebug() << dist << radius << dist / radius;

                m_bResizing = true;

            }

            else

            {

                m_bResizing = false;

            }

        }

        else

        {

            qDebug() << "Custom item left clicked.";

            QGraphicsItem::mousePressEvent(event);

            event->accept();

        }

    }

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

    {

        qDebug() << "Custom item right clicked.";

        event->ignore();

    }

}

 

void CustomItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)

{

    if ((event->modifiers() == Qt::AltModifier) && m_bResizing)

    {

        QPointF pos = event->scenePos();

        double dist = sqrt(pow(m_centerPointF.x()-pos.x(), 2) + pow(m_centerPointF.y()-pos.y(), 2));

        setRect(m_centerPointF.x()-this->pos().x()-dist, m_centerPointF.y()-this->pos().y()-dist, dist*2, dist*2);

    }

    else if(event->modifiers() != Qt::AltModifier)

    {

        qDebug() << "Custom item moved.";

        QGraphicsItem::mouseMoveEvent(event);

        qDebug() << "moved" << pos();

    }

}

 

void CustomItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)

{

    if ((event->modifiers() == Qt::AltModifier) && m_bResizing)

    {

        m_bResizing = false;

    }

    else

    {

        QGraphicsItem::mouseReleaseEvent(event);

    }

}

 

int CustomItem::type() const

{

    return UserType + 1;

}

 

// 自定义 Scene

void CustomScene::mousePressEvent(QGraphicsSceneMouseEvent *event)

{

    qDebug() << "Custom scene clicked.";

    QGraphicsScene::mousePressEvent(event);

    if (!event->isAccepted())

    {

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

        {

            //  Scene 上添加一个自定义 item

            QPointF point = event->scenePos();

            CustomItem *item = new CustomItem();

            item->setRect(point.x()-25, point.y()-25, 60, 60);

            addItem(item);

        }

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

        {

            // 检测光标下是否有 item

            QGraphicsItem *itemToRemove = NULL;

            foreach (QGraphicsItem *item, items(event->scenePos()))

            {

                if (item->type() == QGraphicsItem::UserType+1)

                {

                    itemToRemove = item;

                    break;

                }

            }

            //  Scene 上移除 item

            if (itemToRemove != NULL)

                removeItem(itemToRemove);

        }

    }

}

 

void CustomScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)

{

    qDebug() << "Custom scene moved.";

    QGraphicsScene::mouseMoveEvent(event);

}

 

void CustomScene::keyPressEvent(QKeyEvent *event)

{

    if (event->key() == Qt::Key_Backspace)

    {

        // 移除全部选中的 items

        qDebug() << "selected items " << selectedItems().size();

        while (!selectedItems().isEmpty())

        {

            removeItem(selectedItems().front());

        }

    }

    else

    {

        QGraphicsScene::keyPressEvent(event);

    }

}

 

#include <QApplication>

#include <QGraphicsView>

#include "customitem.h"

 

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

{

    QApplication a(argc, argv);

 

    // 建立 item

    CustomItem *pItem = new CustomItem();

    pItem->setRect(20, 20, 60, 60);

 

    //  item 添加至场景中

    CustomScene scene;

    scene.setSceneRect(0, 0, 400, 300);

    scene.addItem(pItem);

 

    // 为视图设置场景

    QGraphicsView view;

    view.setScene(&scene);

    view.show();

 

    return a.exec();

}

 

 

只是一些事件的应用,懒得看也行

 

 

QGraphicsItemGroup图元分组

 // 构造 group、椭圆、直线、矩形

    QGraphicsItemGroup *pGroup = new QGraphicsItemGroup();

    QGraphicsEllipseItem *pFrom = new QGraphicsEllipseItem();

    QGraphicsLineItem *pLink = new QGraphicsLineItem();

    QGraphicsRectItem *pTo = new QGraphicsRectItem();

 

    // 设置 group 可选中、可移动

    pGroup->setFlags( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable);

 

    // 设置样式(画笔 - 边框色 画刷 - 背景色)

    QPen pen = pFrom->pen();

    pen.setWidth(2);

    pen.setColor(QColor(0, 160, 230));

    pFrom->setPen(pen);

    pLink->setPen(pen);

    pTo->setPen(pen);

    pFrom->setBrush(QColor(247, 160, 57));

    pTo->setBrush(QColor(247, 160, 57));

 

    //  item 添加至 group

    pGroup->addToGroup(pFrom);

    pGroup->addToGroup(pTo);

    pGroup->addToGroup(pLink);

 

    // 设置椭圆、矩形区域

    const double length = 50;

    pFrom->setRect(QRectF(-length/2.0, -length/2.0, length, length));

    pTo->setRect(QRectF(-length/2.0, -length/2.0, length, length));

 

    // 设置椭圆、矩形、链接线坐标

    pFrom->setPos(80, 80);

    pTo->setPos(200, 150);

    pLink->setLine(QLineF(pFrom->pos(), pTo->pos()));

 

    //  group 添加至场景中

    QGraphicsScene *pScene = new QGraphicsScene();

    pScene->setSceneRect(0, 0, 300, 200);

    pScene->addItem(pGroup);

 

    // 为视图设置场景

    QGraphicsView *pView = new QGraphicsView();

    pView->setRenderHint(QPainter::Antialiasing);

    pView->setScene(pScene);

    pView->show();

 

分组的事件处理

void QGraphicsItem::setHandlesChildEvents(bool enabled)

自定义选址选中样式

void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) Q_DECL_OVERRIDE 

{

       QStyleOptionGraphicsItem op;

       op.initFrom(widget);

 

       // 判断选中时,设置状态为 State_None

       if (option->state & QStyle::State_Selected)

           op.state = QStyle::State_None; ;

 

       // 调用默认方法,进行原始绘制

       QGraphicsEllipseItem::paint(painter, &op, widget);

 

       // 选中时绘制

       if (option->state & QStyle::State_Selected) {

           qreal itemPenWidth = pen().widthF();

           const qreal pad = itemPenWidth / 2;

           const qreal penWidth = 0;

 

           // 边框区域颜色

           QColor color = QColor(Qt::yellow);

 

           // 绘制实线

           painter->setPen(QPen(color, penWidth, Qt::SolidLine));

           painter->setBrush(Qt::NoBrush);

           painter->drawRect(boundingRect().adjusted(pad, pad, -pad, -pad));

 

           // 绘制虚线

           painter->setPen(QPen(color, 0, Qt::DashLine));

           painter->setBrush(Qt::NoBrush);

           painter->drawRect(boundingRect().adjusted(pad, pad, -pad, -pad));

       }

   }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

13. 动画框架和状态机

 

 

描述

QAbstractAnimation

全部动画类的基类

QAnimationGroup

动画容器类的抽象基类

QEasingCurve

动画控制的缓和曲线类

QParallelAnimationGroup

并行动画容器

QPauseAnimation

QSequentialAnimationGroup暂停

QPropertyAnimation

Qt的动画属性

QSequentialAnimationGroup

串行动画容器

QTimeLine

控制动画的时间轴类

QVariantAnimation

动画类的抽象基类

 

 

 

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

{

    QApplication a(argc, argv);

 

 

    QPushButton button("Animated Button");

    button.show();

 

    QPropertyAnimation animation(&button, "geometry");

    animation.setDuration(10000);

//    animation.setStartValue(QRect(0, 0, 100, 30));

//    animation.setEndValue(QRect(250, 250, 100, 30));

    animation.setKeyValueAt(0, QRect(0, 0, 100, 30));

    animation.setKeyValueAt(0.8, QRect(250, 250, 100, 30));

    animation.setKeyValueAt(1, QRect(0, 0, 100, 30));

    animation.setEasingCurve(QEasingCurve::OutBounce);//along the line

    animation.start();

    return a.exec();

}

动画分组

   QPushButton button("Animated Button");

    QPushButton *bonnie = new QPushButton("Bonnie");

    bonnie->show();

 

    QPushButton *clyde = new QPushButton("Clyde");

    clyde->show();

 

    // 动画一

    QPropertyAnimation *anim1 = new QPropertyAnimation(bonnie, "geometry");

 

    // 动画二

    QPropertyAnimation *anim2 = new QPropertyAnimation(clyde, "geometry");

 

    QParallelAnimationGroup *group = new QParallelAnimationGroup;

    group->addAnimation(anim1);

    group->addAnimation(anim2);

 

    group->start();

点击移动

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

{

    QApplication a(argc, argv);

 

 

    QPushButton *button = new QPushButton("Animated Button");

    button->show();

 

    QStateMachine *machine = new QStateMachine;

 

    QState *state1 = new QState(machine);

    state1->assignProperty(button, "geometry", QRect(500, 500, 100, 30));

    machine->setInitialState(state1);

 

    QState *state2 = new QState(machine);

    state2->assignProperty(button, "geometry", QRect(250, 250, 100, 30));

 

    QSignalTransition *transition1 = state1->addTransition(button,

        SIGNAL(clicked()), state2);

    transition1->addAnimation(new QPropertyAnimation(button, "geometry"));

 

    QSignalTransition *transition2 = state2->addTransition(button,

        SIGNAL(clicked()), state1);

    transition2->addAnimation(new QPropertyAnimation(button, "geometry"));

 

    machine->start();

    return a.exec();

}

自定义属性之改变透明度

#ifndef MAIN_WINDOW_H

#define MAIN_WINDOW_H

 

...

 

class MainWindow : public CustomWindow

{

    Q_OBJECT

    Q_PROPERTY(int alpha READ alpha WRITE setAlpha)

 

public:

    explicit MainWindow(QWidget *parent = 0);

    ~MainWindow();

 

private:

    int alpha() const;

    void setAlpha(const int alpha);

 

private:

    int m_nAlpha;

    QLabel *m_pLabel;

};

 

#endif // MAIN_WINDOW_H

 

void MainWindow::setAlpha(const int alpha)

{

    m_nAlpha = alpha;

    QString strQSS = QString("color: rgb(0, 160, 230); background-color: rgba(10, 160, 105, %1);").arg(m_nAlpha);

    m_pLabel->setStyleSheet(strQSS);

}

 

QPropertyAnimation *pAnimation = new QPropertyAnimation();

    pAnimation->setTargetObject(this);

    pAnimation->setPropertyName("alpha");

    pAnimation->setDuration(1000);

    pAnimation->setKeyValueAt(0, 255);

    pAnimation->setKeyValueAt(0.5, 100);

    pAnimation->setKeyValueAt(1, 255);

pAnimation->setLoopCount(-1);  //永远运行,直到stop

 

动画的组操做

(1)单操做

 m_pGroup = new QSequentialAnimationGroup(this);

 

 // 添加动画

 m_pGroup->addAnimation(pAnimation1);

 

 // 暂停1

 m_pGroup->addPause(1000);

 m_pGroup->addAnimation(pAnimation2);

 

 // 循环2

 m_pGroup->setLoopCount(2);

 

 // 从后向前执行

 m_pGroup->setDirection(QAbstractAnimation::Backward);

(2)并行操做

 m_pGroup = new QParallelAnimationGroup(this);

     

         // 添加动画

         m_pGroup->addAnimation(pAnimation1);

         m_pGroup->addAnimation(pAnimation2);

     

         // 循环2

         m_pGroup->setLoopCount(2);

(3)暂停

 // 暂停 - 特殊的动画

             QPauseAnimation *pPauseAnimation = new QPauseAnimation(this);

             pPauseAnimation->setDuration(1000);

         // 添加动画

             m_pGroup->addAnimation(pAnimation1);

             m_pGroup->addAnimation(pPauseAnimation);

             m_pGroup->addAnimation(pAnimation2);

时间控制

QProgressBar *progressBar = new QProgressBar(this);

    progressBar->setRange(0, 100);

    

    // 构造帧范围为 0 - 100,持续时间为 1000 毫秒(1 秒)的 timeline

    QTimeLine *timeLine = new QTimeLine(1000, this);

    timeLine->setFrameRange(0, 100);

    connect(timeLine, SIGNAL(frameChanged(int)), progressBar, SLOT(setValue(int)));

    

    // 输出当前帧数

    connect(timeLine, &QTimeLine::frameChanged, [=](int value) {

            qDebug() << value;

        });

    

    // 启动进度条动画

    QPushButton *startButton = new QPushButton(this);

    startButton->setText(QString::fromLocal8Bit("开始"));

    connect(startButton, SIGNAL(clicked()), timeLine, SLOT(start()));

下坠效果

void MainWindow::onDropWindow()

{

    QPropertyAnimation *pAnimation = new QPropertyAnimation(this, "geometry");

 

    QDesktopWidget *pDesktopWidget = QApplication::desktop();

    int x = (pDesktopWidget->availableGeometry().width() - width()) / 2;

    int y = (pDesktopWidget->availableGeometry().height() - height()) / 2;

 

    pAnimation->setDuration(1000);

    pAnimation->setStartValue(QRect(x, 0, width(), height()));

    pAnimation->setEndValue(QRect(x, y, width(), height()));

    pAnimation->setEasingCurve(QEasingCurve::OutElastic);

    pAnimation->start(QAbstractAnimation::DeleteWhenStopped);

}

抖动效果和透明效果

void MainWindow::onOpacityWindow()

{

    QPropertyAnimation *pAnimation = new QPropertyAnimation(this, "windowOpacity");

    pAnimation->setDuration(1000);

    pAnimation->setKeyValueAt(0, 1);

    pAnimation->setKeyValueAt(0.5, 0);

    pAnimation->setKeyValueAt(1, 1);

    pAnimation->start(QAbstractAnimation::DeleteWhenStopped);

}

void MainWindow::onShakeWindow()

{

    QPropertyAnimation *pAnimation = new QPropertyAnimation(this, "pos");

    pAnimation->setDuration(500);

    pAnimation->setLoopCount(2);

    pAnimation->setKeyValueAt(0, QPoint(geometry().x() - 3, geometry().y() - 3));

    pAnimation->setKeyValueAt(0.1, QPoint(geometry().x() + 6, geometry().y() + 6));

    pAnimation->setKeyValueAt(0.2, QPoint(geometry().x() - 6, geometry().y() + 6));

    pAnimation->setKeyValueAt(0.3, QPoint(geometry().x() + 6, geometry().y() - 6));

    pAnimation->setKeyValueAt(0.4, QPoint(geometry().x() - 6, geometry().y() - 6));

    pAnimation->setKeyValueAt(0.5, QPoint(geometry().x() + 6, geometry().y() + 6));

    pAnimation->setKeyValueAt(0.6, QPoint(geometry().x() - 6, geometry().y() + 6));

    pAnimation->setKeyValueAt(0.7, QPoint(geometry().x() + 6, geometry().y() - 6));

    pAnimation->setKeyValueAt(0.8, QPoint(geometry().x() - 6, geometry().y() - 6));

    pAnimation->setKeyValueAt(0.9, QPoint(geometry().x() + 6, geometry().y() + 6));

    pAnimation->setKeyValueAt(1, QPoint(geometry().x() - 3, geometry().y() - 3));

    pAnimation->start(QAbstractAnimation::DeleteWhenStopped);

}

相关文章
相关标签/搜索