1 Qt-VS-Addin插件使用方法

1、VS中点击Qt 设置

2、点击add,添加的路径是到该Qt版本下的bin文件夹的上一级文件夹,添加成功

2 Qt默认编译输出位置

../%{CurrentProject:Name}/%{CurrentKit:FileSystemName}

3 关于Qt Designer.exe无法启动的问题

C:UsersSandeepin.designergradients.xml

删除gradients.xml文件即可。这个.xml文件是Qt Desinder的配置文件,出现打不开的问题我想就是启动配置出现了问题了。

Qt 5.6.2找到了对应Qt bug但还是打开状态。地址如下:https://bugreports.qt.io/browse/QTBUG-53984

根据bug描述应该是在win10 64位系统并且是双显卡的情况下,Qt5WebEngineWidgets.dll在designer启动时会卡住,最终导致designer一直不显示界面。

Qt5WebEngineWidgets.dll这个文件,重命名比如后缀加个.bak,可以打开但不知道会有什么影响

4 Qt5 for vs2013 中文乱码解决办法

在使用中文的文件头部添加这条语句:

pragma execution_character_set("utf-8")

5 使用自带的windeployqt生成exe依赖发布软件

假设自己编译的程序名字为poi.exe,放在C:QtQt5.6.25.6mingw49_32Sandeepin”里面。

在开始菜单Qt5.6下找到Qt 5.6 for Desktop (MinGW 4.9.2 32 bit)cmd运行文件,打开运行。

cmd进入 “C:QtQt5.6.25.6mingw49_32Sandeepin” 下, 执行命令windeployqt 1.exe

然后在 “C:QtQt5.6.25.6mingw49_32Sandeepin” 下就可以看到发布的文件,解决了依赖关系,直接可以运行。

6 cout输出Qt类型字符串

#include <QTextStream>
QTextStream cin(stdin, QIODevice::ReadOnly);
QTextStream cout(stdout, QIODevice::WriteOnly);
QTextStream cerr(stderr, QIODevice::WriteOnly);

QString str ="123";
cout<<str<<endl; // 必须加endl才能输出

7 各种类型字符串转换

常用参数类型:

char* 字符串

QByteArray 字符数组

QString Qt字符串

1、char* 转 QByteArray(调用构造函数)

char* str;

QByteArray byte(str);

2、char 转 QString(const char)(调用构造函数)

char* str;

QString string(str);

3、QByteArray 转 char*(调用.data())

QByteArray byte;

char* str = byte.data();

4、QByteArray 转 QString(调用构造函数)

QByteArray byte;

QString string(byte);

5、QString 转 QByteArray(调用toLatin1())

QString string;

QByteArray byte = string.toLatin1();

6、QString 转const char(调用qPrintable(),只发现转const char的方法)

QString string;

const char* str = qPrintable(string);

QString与string的转换

QString到string: QString.toStdString();

string到QString: QString::fromStdString(string);

8 字符串与int、double等数字之间转换

主要讲解QString转int和double

1、QString转int和double

QString str="123.45";

double val=str.toDouble();

QString str="123.45";

float d=str.toFloat();

QString str="123";

int dd=str.toInt();

2、int和double转QString

long a =63;

QString str=QString::number(a); //10进制默认

QString str=QString::number(a,16); //16进制

double b=123456789.0987654321;

QString str=QString::number(b, 10, 4);// double数据、进制数、精度

9 加图标

方法1:

poi.ico文件放在pro文件同一目录,pro文件中直接添加:

RC_ICONS = poi.ico

方法2:

Qt Creator – 文件 – 新建文件或项目 – 文件和类中选择 Qt – Qt 资源文件。

单击选择-给资源文件起个名字,可自己定义,如image。

单击 image.qrc 文件 – 单击[添加]按钮 [添加前缀] –在单击 [添加文件]选择刚刚项目中准备的 ICO 图片,单击 resource/QT.ico 给图片起一个别名,这里命名为 ico。

在 mainwindow.cpp 中添加代码。

this->setWindowIcon(QIcon(":/new/prefix1/ico"));//窗体 ICO 图片,如图不起别名,后缀直接写图片全名。

10 设计菜单例子

简单的例子,在动作编辑面板中选择一个动作点击后,可以选择“转到槽”:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setWindowTitle("艹");  //设置窗口标题
    this->resize(1024,768);      //设置窗口大小
    //this->close();
    //this->setCentralWidget(ui->pushButton);//设置中心部件
    //this->showFullScreen();  //全屏显示,无标题栏
    //this->showMaximized();  //最大化显示
    //this->showMinimized();  //最小化显示
    //this->showNormal();     //正常显示
    //this->update();         //更新显示
}
void MainWindow::on_Fuck_triggered()
{
    QMessageBox::information(this,"Fuck按下","poi Fuck");//包含头文件#include <QMessageBox>
}

void MainWindow::on_actionExit_triggered()
{
    close();//关闭程序
}

11 窗体相关设置

1、控制窗体大小

    this->setWindowTitle("异想家sandeepin");        // 设置窗口标题
    this->resize(1024,768);                            // 设置窗口大小
    this->setCentralWidget(ui->pushButton);            // 设置中心部件
    this->showFullScreen();                            // 全屏显示,无标题栏
    this->showMaximized();                            // 最大化显示
    this->showMinimized();                            // 最小化显示
    this->showNormal();                                // 正常显示
    this->update();                                    // 更新显示
    this->setMaximumSize(1024,768);                    // 窗体最大 1024*768
    this->setMinimumSize(300,300);                    // 窗体最小 300*300

2、窗体初始位置及背景色

    this->move(0,0); //默认窗体居中显示,如果想要更改用 move 或 setGeometry;(0,0)代表最左上角
    this->setStyleSheet("background:red");//背景红色

3、 移动无边框窗体

打开 mainwindow.h 头文件,添加代码。

#include <QMouseEvent>  //引用鼠标类头文件
#include <QPushButton>  //引用按钮类头文件

//定义鼠标三种状态方法
protected:
    void mousePressEvent(QMouseEvent *e);//鼠标按下
    void mouseMoveEvent(QMouseEvent *e);//鼠标移动
    void mouseReleaseEvent(QMouseEvent *e);//鼠标释放

private:
    QPushButton *btClose;//定义关闭按钮
    QPoint last;//定义 QPoint 对象

打开 mainwindow.cpp 源代码文件,添加代码。

this->setWindowFlags(Qt::FramelessWindowHint);//去掉标题栏
btClose = new QPushButton(this);//实例一个按钮控件,因为去掉标题栏后,窗体没有关闭按钮了。
btClose->setText("关闭");//所以自己添加一个按钮实现关闭功能。
connect(btClose,SIGNAL(clicked()),this,SLOT(close()));//按钮点击事件

//获取鼠标点定位窗体位置
void MainWindow::mousePressEvent(QMouseEvent *e)
{
    last = e->globalPos();
}

void MainWindow::mouseMoveEvent(QMouseEvent *e)
{
    int dx = e->globalX() - last.x();
    int dy = e->globalY() - last.y();
    last = e->globalPos();
    move(x()+dx,y()+dy);
}

void MainWindow::mouseReleaseEvent(QMouseEvent *e)
{
    int dx = e->globalX() - last.x();
    int dy = e->globalY() - last.y();
    move(x()+dx, y()+dy);
}

4、去掉标题栏中最大化、最小化按钮

    this->setWindowFlags(Qt::WindowMinMaxButtonsHint);//关闭按钮失效
    this->setWindowFlags(Qt::WindowCloseButtonHint);//去掉最大化、最小化按钮,保留关闭按钮

5、多窗体调用

实现从 MainWindow 窗体点击按钮打开 MainWindow2 窗体。

文件-新建文件或项目-文件和类-Qt-Qt 设计师界面类-Main Window,取名 MainWindow2

打开 MainWindow.h 头文件,编写代码。

#include <QPushButton>  //引用 QPushButonn 类
#include <mainwindow2.h>   //引用 mainwindow2 类


//实例按钮
private:
    QPushButton *button;
    MainWindow2 w2;
//实例方法
private slots:
    void showMainwindow2();

打开 MainWindow.cpp 文件,编写代码。

button = new QPushButton(this);//实例 QPushButonn 控件
button->setGeometry(QRect(50,50,100,25));//按钮显示位置
button->setText("按钮");//按钮值
connect(button,SIGNAL(clicked()),this,SLOT(showMainwindow2()));//点击事件

//调用方法
void MainWindow::showMainwindow2()
{
    w2.show(); //显示 MainWindow2 窗体
}

6、字体形状窗体

实现将窗体背景色透明,根据图片形状显示窗体。

添加资源文件,将透明图片文字拷贝到项目中。添加图片之后,打开 MainWindow.cpp 文件编写如下代码。

//去掉标题栏
this->setWindowFlags(Qt::FramelessWindowHint);
//设置背景透明
this->setAttribute(Qt::WA_TranslucentBackground, true);
//窗体添加样式,样式为 CSS 样式表
// background-image:url 添加图片
// background-repeat:no-repeat 不平铺
this->setStyleSheet("background-image:url(:/new/prefix1/poiimg);background-repeat:no-repeat;");

12 、控件应用

最方便的方法是通过ui拖动操作,为了理解代码本质,本例均用代码实现。

12.1 QPushButton 按钮

实现在窗体中创建按钮 A,点击按钮 A,改变文字为按钮 B。

打开 MainWindow.h 文件编写如下代码。

#include <QPushButton>

private:
    QPushButton *button1;//声明 QPushButton
private slots:
    void txtButton();//声明 QPushButton 方法

打开 MainWindow.cpp 文件编写如下代码。

button1 = new QPushButton("按钮 A",this);//创建按钮
button1->setGeometry(QRect(100,100,100,25));//定义按钮 X 轴,Y 轴,W 宽,H 高
connect(button1,SIGNAL(released()),this,SLOT(txtButton()));//给按钮添加插槽事件(点击事件)
//点击方法
void MainWindow::txtButton()
{
    button1->setText("按钮 B");//改变按钮文字
}

12.2 QLabel 标签

实现在窗体中创建 QLabel 标签显示“我是 QLabel”字样,红色加粗倾斜字体。

打开 MainWindow.h 文件编写如下代码。

include

private:
    QLabel *label1;//声明 QLabel

打开 MainWindow.cpp 文件编写如下代码。
label1 = new QLabel("我是 QLabel",this);//实例 QLabel 控件
//label1->move(100,100);//QLabel 位置
label1->setGeometry(QRect(100,100,200,30));
//label1 样式(CSS 样式表)
//font-size 字号
//color 字体颜色
//font-weight 字宽
//font-style 字体样式
label1->setStyleSheet("font-size:20px;color:red;font-weight:bold;font-style:italic");

12.3 QLineEdit 单行文本

打开 MainWindow.h 文件编写如下代码。

#include <QLineEdit>
private:
    QLineEdit *lineEdit1;//声明 QLineEdit 控件

打开 MainWindow.cpp 文件编写如下代码。
lineEdit1 = new QLineEdit(this);//创建 QLineEdit 控件
lineEdit1->setGeometry(QRect(100,100,200,25));//位置大小
//样式
//border 边框线大小
//border-style 边框样式 solid 实线
//border-color:blue red 上下蓝色 左右红色  
lineEdit1->setStyleSheet("border:1px;border-style:solid;color:red;border-color: blue red;");
lineEdit1->setMaxLength(12);//限制最长输入 12 位
//lineEdit1->setEchoMode(QLineEdit::NoEcho);//不可写入
lineEdit1->setEchoMode(QLineEdit::Password);//密码*号输入

12.4 QTextEdit 多行文本

打开 MainWindow.h 文件编写如下代码。

#include <QTextEdit>
private:
    QTextEdit *textEdit1;//声明 textEdit1 控件

打开 MainWindow.cpp 文件编写如下代码。
textEdit1 = new QTextEdit(this);//实例 QTextEdit 控件
textEdit1->setGeometry(QRect(50,50,200,150));//控件位置大小
textEdit1->setText("我是第一行<br/>我是第二行");//内容

12.5 QPlainTextEdit 多行文本

QT中 LineEdit、TextEdit、PlainTextEdit 这三个控件有什么区别,分别用在什么情况下呢?

答:

QLineEdit是单行文本输入,一般用于用户名、密码等少量文本交互地方。

QTextEdit用于多行文本,也可以显示HTML格式文本。

QPlainTextEdit与QTextEdit很像,但它多用于需要与文本进行处理的地方,而QTextEdit多用于显示,可以说,QPlainTextEdit对于PlainText处理能力比QTextEdit强。

打开 MainWindow.h 文件编写如下代码。

#include <QPlainTextEdit>
private:
     QPlainTextEdit *plainTextEdit1;//声明 plainTextEdit1 控件
     
打开 MainWindow.cpp 文件编写如下代码。
plainTextEdit1 = new QPlainTextEdit(this);//实例
plainTextEdit1->setGeometry(QRect(100,50,200,100));//位置
plainTextEdit1->setPlainText("第一行");//添加内容

12.6 QComboBox 下拉列表框

打开 MainWindow.h 文件编写如下代码。

#include <QComboBox>
private:
    QComboBox *comboBox1;

打开 MainWindow.cpp 文件编写如下代码。

comboBox1 = new QComboBox(this);//实例 QComboBox1
comboBox1->setGeometry(QRect(50,50,120,25));//控件显示位置大小
QStringList str;//定义字符串列表
str << "数学" << "语文" << "地理";
comboBox1->addItems(str);//将字符串列表绑定 QComboBox 控件

12.7 QTimeEdit 时间控件

打开 MainWindow.h 文件编写如下代码。

#include <QTimeEdit>
private:
    QTimeEdit *timeEdit;

打开 MainWindow.cpp 文件编写如下代码。

timeEdit = new QTimeEdit(this);//实例
timeEdit->setGeometry(QRect(50,50,120,25));//位置
QDateTime sysTime1 = QDateTime::currentDateTime();//获取系统时间
QStringList list1 = sysTime1.toString("hh:mm:ss").split(':');//获取时分秒以“:”号拆分赋予 list 数组
timeEdit->setTime(QTime(list1[0].toInt(),list1[1].toInt(),list1[2].toInt()));//将时分秒绑定控件  

12.8 QDateEdit 日期控件

打开 MainWindow.h 文件编写如下代码。

#include <QDateEdit>
private:
    QDateEdit *dateEdit;

打开 MainWindow.cpp 文件编写如下代码。

dateEdit = new QDateEdit(this);//实例
dateEdit->setGeometry(QRect(50,50,120,25));//位置
QDateTime sysTime2 = QDateTime::currentDateTime();//获取系统时间
QStringList list2 = sysTime2.toString("yyyy-MM-dd").split('-');//获取时分秒以“-”号拆分赋予 list 数组
dateEdit->setDate(QDate(list2[0].toInt(),list2[1].toInt(),list2[2].toInt()));//将年月日绑定控件  

12.9 QScrollBar 控件

打开 MainWindow.h 文件编写如下代码。

#include <QScrollBar>
#include <QSpinBox>
private:
    QScrollBar *scrollBar;
    QSpinBox *spinBox;

打开 MainWindow.cpp 文件编写如下代码。

scrollBar = new QScrollBar(this);//实例
spinBox = new QSpinBox(this);
scrollBar->setOrientation(Qt::Horizontal);//横显/竖显
scrollBar->setGeometry(QRect(50,50,180,20));//位置
spinBox->setGeometry(QRect(50,90,100,25));
scrollBar->setPageStep(10);//控制条宽度
connect(scrollBar,SIGNAL(valueChanged(int)),spinBox,SLOT(setValue(int)));//scrollBar 事件 
connect(spinBox,SIGNAL(valueChanged(int)),scrollBar,SLOT(setValue(int)));//spinBox 事件  
scrollBar->setValue(50);//初始值

12.10 QRadioButton 单选按钮

打开 MainWindow.h 文件编写如下代码。

#include <QRadioButton>
#include <QLabel>

private slots:
    void radioChange();
private:
    QRadioButton *radioM;
    QRadioButton *radioW;
    QLabel *label;

打开 MainWindow.cpp 文件编写如下代码。

radioM = new QRadioButton(this);//实例
radioW = new QRadioButton(this);
label = new QLabel(this);
radioM->setGeometry(QRect(50,50,50,50));//位置
radioW->setGeometry(QRect(100,50,50,50));
label->setGeometry(QRect(50,100,100,25));
radioM->setText("男");
radioW->setText("女");
radioM->setChecked(true);//默认选择
label->setText("男");
connect(radioM,SIGNAL(clicked()),this,SLOT(radioChange()));//事件
connect(radioW,SIGNAL(clicked()),this,SLOT(radioChange()));

//Radio 点击方法
void MainWindow::radioChange()
{
    if(sender() == radioM)
    {
        label->setText("男");
    }else if(sender() == radioW)
    {
        label->setText("女");
    }
}

12.11 QCheckBox 复选框

打开 MainWindow.h 文件编写如下代码。

#include <QCheckBox>
#include <QLabel>
private slots:
    void checkChange();
private:
    QCheckBox *checkBox01;
    QCheckBox *checkBox02;
    QCheckBox *checkBox03;
    QLabel *label;

打开 MainWindow.cpp 文件编写如下代码。

checkBox01 = new QCheckBox(this);//实例化 checkBox 控件
checkBox02 = new QCheckBox(this);
checkBox03 = new QCheckBox(this);
label = new QLabel(this);//实例 label 控件显示结果
checkBox01->setGeometry(QRect(50,50,50,50));//控件位置
checkBox02->setGeometry(QRect(100,50,50,50));
checkBox03->setGeometry(QRect(150,50,50,50));
label->setGeometry(QRect(50,100,200,30));
checkBox01->setText("数学");//控件值
checkBox02->setText("语文");
checkBox03->setText("地理");
connect(checkBox01, SIGNAL(clicked(bool)), this, SLOT(checkChange()));//checkbox 控件点击事件
connect(checkBox02, SIGNAL(clicked(bool)), this, SLOT(checkChange()));
connect(checkBox03, SIGNAL(clicked(bool)), this, SLOT(checkChange()));


//定义接收变量
QString str;
void MainWindow::checkChange()
{
    if(sender() == checkBox01)
    {
        //判断是否被选中
        if(checkBox01->checkState() == Qt::Checked)
        {
            str += "数学";
        }else
        {
            str = str.replace(QString("数学"),QString(""));
        }
    }else if(sender() == checkBox02)
    {
        if(checkBox02->checkState() == Qt::Checked)
        {
            str += "语文";
        }else
        {
            str = str.replace(QString("语文"),QString(""));
        }
    }else if(sender() == checkBox03)
    {
        if(checkBox03->checkState() == Qt::Checked)
        {
            str += "地理";
        }else
        {
            str = str.replace(QString("地理"),QString(""));
        }
    }
    //绑定值
    label->setText(str);
}

12.12 QListView 列表控件

打开 MainWindow.h 文件编写如下代码。

#include <QListView>        //QListView 类
#include <QStringListModel> //数据模型类
private:
    QListView *listView;
    QStringListModel *model;

打开 MainWindow.cpp 文件编写如下代码。

listView = new QListView(this);//实例 listView 控件
listView->setGeometry(QRect(50,50,100,100));//定义位置宽高
QStringList string;//StringList 数组
string << "数学" << "语文" << "外语" <<"地理";
model = new QStringListModel(string);//添加数据
listView->setModel(model);//将数据绑定 listView 控件

12.13 QHBoxLayout 横向布局

打开 MainWindow.h 文件编写如下代码。

#include <QHBoxLayout>
#include <QPushButton>
#include <QWidget>
private:
    QHBoxLayout *hboxLayout;
    QPushButton *button1;
    QPushButton *button2;
    QPushButton *button3;
    QWidget *widget;

打开 MainWindow.cpp 文件编写如下代码。

hboxLayout = new QHBoxLayout();//创建横向布局
button1 = new QPushButton("按钮 1");
button2 = new QPushButton("按钮 2");
button3 = new QPushButton("按钮 3");
hboxLayout->addWidget(button1);//向布局中添加控件
hboxLayout->addWidget(button2);
hboxLayout->addWidget(button3);
hboxLayout->setSpacing(60);//间隔
widget = new QWidget();//实例 QWidget
widget->setLayout(hboxLayout);//绑定布局
this->setCentralWidget(widget);//绑定界面

QGridLayout 网格布局、纵向布局类似,这里不作赘述。

12.14 QGroupBox 控件

打开 MainWindow.h 文件编写如下代码。

#include <QGroupBox>
#include <QPushButton>
#include <QVBoxLayout>
private:
    QGroupBox *box;
    QPushButton *button;
    QVBoxLayout *vbox;

打开 MainWindow.cpp 文件编写如下代码。

box = new QGroupBox(this);//实例 QGroupBox
box->setGeometry(QRect(300,300,340,100));//位置、大小
box->setTitle("语音栏目");//标题
button = new QPushButton();//实例按钮
button->setText("按钮");
vbox = new QVBoxLayout;//实例布局
vbox->addWidget(button);//将按钮加入布局
box->setLayout(vbox);//将布局加入 QGroupBox 控件

12.15 QTabWidget 控件

打开 MainWindow.h 文件编写如下代码。

#include <QTabWidget>

private:
QTabWidget *tabWidget;

//tabA 类
class tabA:public QWidget
{
    Q_OBJECT
public:
    tabA(QWidget *parent=0);
};
//tabB 类
class tabB:public QWidget
{
    Q_OBJECT
public:
    tabB(QWidget *parent=0);
};

打开 MainWindow.cpp 文件编写如下代码。

#include <QWidget>
#include <QPushButton>

//实例 QTabWidget
tabWidget = new QTabWidget(this);
tabWidget->setGeometry(QRect(30,30,340,140));
tabWidget->addTab(new tabA,"A 栏目");
tabWidget->addTab(new tabB,"B 栏目");

tabA::tabA(QWidget *parent):QWidget(parent)
{
    QPushButton *buttonA = new QPushButton(this);
    buttonA->setText("页面 A");
}
tabB::tabB(QWidget *parent):QWidget(parent)
{
    QPushButton *buttonB = new QPushButton(this);
    buttonB->setText("页面 B");
}

12.16 QMenu、QToolBar 控件

打开 MainWindow.h 文件编写如下代码。

#include <QMenu>
#include <QMenuBar>
#include <QAction>
#include <QToolBar>

private:
    QMenu *fileMenu, *editMenu, *helpMenu;
    QToolBar *fileToolBar, *editToolBar;
    QAction *newAct;
    QAction *cutAct;
    QAction *copyAct;
    QAction *pasteAct;
    QAction *aboutQtAct;
private slots:
    void newFile();

打开 MainWindow.cpp 文件编写如下代码。

#include <QMessageBox>
//实例菜单
fileMenu = new QMenu(this);
editMenu = new QMenu(this);
helpMenu = new QMenu(this);
//填充菜单子节点
newAct =  new  QAction(QIcon( ":/images/new" ), tr( "新建" ),  this );
newAct->setShortcut(tr("Ctrl+N" ));
newAct->setStatusTip(tr("新建文件" ));
connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));
cutAct = new  QAction(QIcon( ":/images/cut" ), tr( "剪切" ),  this );
cutAct->setShortcut(tr("Ctrl+X" ));
cutAct->setStatusTip(tr("剪切内容" ));
copyAct = new  QAction(QIcon( ":/images/copy" ), tr( "复制" ),  this );
copyAct->setShortcut(tr("Ctrl+C" ));
copyAct->setStatusTip(tr("复制内容" ));
pasteAct = new  QAction(QIcon( ":/images/paste" ), tr( "粘贴" ),  this );
pasteAct->setShortcut(tr("Ctrl+V" ));
pasteAct->setStatusTip(tr("粘贴内容" ));
aboutQtAct = new  QAction(tr( "关于 Qt" ),  this );
aboutQtAct->setStatusTip(tr("关于 Qt 信息" ));
connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
//填充菜单
fileMenu = menuBar()->addMenu(tr( "文件" ));
fileMenu->addAction(newAct);
fileMenu->addSeparator();
editMenu = menuBar()->addMenu(tr("编辑" ));
editMenu->addAction(cutAct);
editMenu->addAction(copyAct);
editMenu->addAction(pasteAct);
menuBar()->addSeparator();
helpMenu = menuBar()->addMenu(tr("帮助" ));
helpMenu->addAction(aboutQtAct);
//toolBar 工具条
fileToolBar = addToolBar(tr("新建"));
fileToolBar->addAction(newAct);
editToolBar = addToolBar(tr("修改"));
editToolBar->addAction(cutAct);
editToolBar->addAction(copyAct);
editToolBar->addAction(pasteAct);

//子菜单事件
void MainWindow::newFile(){
    QMessageBox::warning(this,tr("Warning"),
                         tr("创建新文件?"),
                         QMessageBox::Yes | QMessageBox::Default,
                         QMessageBox::No);
}

12.17 任务栏托盘菜单

打开 MainWindow.h 文件编写如下代码。

#include <QSystemTrayIcon>//任务栏类
#include <QMenu>//菜单类

private:
    QSystemTrayIcon *myTrayIcon;
    QMenu *myMenu;
    QAction *restoreWinAction;
    QAction *quitAction;
    void createMenu();
private slots:
    void showNormal();

打开 MainWindow.cpp 文件编写如下代码。

createMenu();//菜单
//判断系统是否支持托盘图标
if(!QSystemTrayIcon::isSystemTrayAvailable())
{
    return;
}
myTrayIcon = new QSystemTrayIcon(this);//实例 QSystemTrayIcon
myTrayIcon->setIcon(QIcon(":/new/prefix1/ico"));//设置图标
myTrayIcon->setToolTip("Qt 托盘图标功能");//鼠标放托盘图标上提示信息
myTrayIcon->showMessage("托盘","托盘管理",QSystemTrayIcon::Information,10000);//设置消息
myTrayIcon->setContextMenu(myMenu);//托盘菜单
myTrayIcon->show();//显示


//绘制菜单
void MainWindow::createMenu()
{
    restoreWinAction = new QAction("恢复(&R)",this);//恢复
    quitAction = new QAction("退出(&Q)",this);//退出
    connect(restoreWinAction,SIGNAL(triggered()),this,SLOT(showNormal()));//恢复
    connect(quitAction,SIGNAL(triggered()),qApp,SLOT(quit()));//退出
    myMenu = new QMenu((QWidget*)QApplication::desktop());
    myMenu->addAction(restoreWinAction);//添加菜单
    myMenu->addSeparator();//分隔符
    myMenu->addAction(quitAction);
}

//恢复
void MainWindow::showNormal()
{
    this->show();
}

//点击最小化按钮隐藏界面
void QWidget::changeEvent(QEvent *e)
{
    if((e->type()==QEvent::WindowStateChange)&&this->isMinimized())
    {
        //QTimer::singleShot(100, this, SLOT(hide()));
        this->hide();
    }
}

12.18 批量调用UI控件

Qt的UI界面编程时,会遇到这种情况,界面上分布大量相同的控件,如LineEdit_1、LineEdit_2、LineEdit_3 等一系列控件。对这么多控件进行操作,无疑采用遍历的方式是最好的办法,可是往往这些控件都是在UI设计器里手动添加的,所以并不能立刻得到可批量操作的地址。

可以声明一系列对应控件类型的指针数组,然后将各个控件的地址复制给指针,然后操作指针数组就可以操作相应的控件。

打开 MainWindow.h 文件编写如下代码。

#include <QLabel>
private:
    QLabel  *QLabelAll[64];

打开 MainWindow.cpp 文件编写如下代码。

    QLabelAll[ 0] = ui->label_2;
    QLabelAll[ 1] = ui->label_3;
    QLabelAll[ 2] = ui->label_4;
    QLabelAll[ 3] = ui->label_5;
    QLabelAll[ 4] = ui->label_6;
    QLabelAll[ 5] = ui->label_7;
    QLabelAll[ 6] = ui->label_8;
    QLabelAll[ 7] = ui->label_9;
    QLabelAll[ 8] = ui->label_10;
    QLabelAll[ 9] = ui->label_11;

    for(int i=0;i<10;i++)
    {
         QLabelAll[i]->setText("");
    }

以上代码实现标签初始化全为空格。但是这种方法有个弊端:在进行初始化复制地址时,如果有很多控件,势必一行语句一个复制,工作量大而且很不优雅。

13 文件操作

创建文件夹可以用按钮事件,或者不用

打开 MainWindow.h 文件编写如下代码。

private:
    void createFolder();

打开 MainWindow.cpp 文件编写如下代码。

#include <QDir>
#include <QMessageBox>
//按钮事件
connect(button,SIGNAL(clicked()),this,SLOT(createFolder()));

void MainWindow::createFolder()
{
    //实例 QDir
    QDir *folder = new QDir;
    QString FileDirName = "poi";
    //判断创建文件夹是否存在
    bool exist = folder->exists(FileDirName);
    if(exist)
    {
        QMessageBox::warning(this,tr("创建文件夹"),tr("文件夹已经存在!"));
    }else
    {
        //创建文件夹
        bool ok = folder->mkdir(FileDirName);
        //判断是否成功
        if(ok)
        {
            QMessageBox::warning(this,tr("创建文件夹"),tr("文件夹创建成功!"));
        }else
        {
            QMessageBox::warning(this,tr("创建文件夹"),tr("文件夹创建失败!"));
        }
    }
}

创建文件举例:

    //实例 QFile
    QFile file("poi\\123.txt");
    QString poi = "poi";
    //判断文件是否存在
    if(file.exists())
    {
        QMessageBox::warning(this,"创建文件","文件已经存在!");
    }
    else
    {
        
        file.open(QIODevice::ReadWrite | QIODevice::Text);//存在打开,不存在创建
        
        QByteArray str = poi.toUtf8();//写入内容,这里需要转码,否则报错。
        
        file.write(str);
        //提示成功
        QMessageBox::warning(this,"创建文件","文件创建成功!");//写入 QByteArray 格式字符串
    }
    //关闭文件
    file.close();

精简版写法:

    QDir *folder = new QDir;    // 实例 QDir
    QString FileDirName = "poi\r\n";// 文件夹名
    //判断创建文件夹是否存在
    bool exist = folder->exists(FileDirName);
    if(exist)
    {
        //什么都不提示
    }else
    {
        //创建文件夹
        folder->mkdir(FileDirName);
    }
    //实例 QFile
    QFile file("poi\\123.txt");
    //存在打开,不存在创建
    file.open(QIODevice::ReadWrite | QIODevice::Append);
    //写入内容,这里需要转码,否则报错。
    QByteArray str = FileDirName.toUtf8();
    //写入 QByteArray 格式字符串
    file.write(str);
    //关闭文件
    file.close();

14 定时器使用

1.新建GUI工程,工程名可以设置为timer。并在主界面上添加一个标签,并设置其内容为”0000-00-00 00:00:00 星期日“。

2.在mainwindow.h中添加槽函数声明。

private slots:
       void timerUpDate();

3.在mainwindow.cpp中添加代码。

添加#include 的头文件包含,这样就包含了QtCore下的所有文件。

构造函数里添加代码:

    //定时器相关
    QTimer *timer = new QTimer(this);//新建定时器
    connect(timer,SIGNAL(timeout()),this,SLOT(timerUpDate()));//关联定时器计满信号和相应的槽函数。
    timer->start(1000); //定时器开始计时,其中1000表示1000ms即1s,每1000ms就会触发一次槽函数。

4.然后实现更新函数。

void MainWindow::timerUpDate()
{
       QDateTime time = QDateTime::currentDateTime();//获取系统现在的时间
       QString str = time.toString("yyyy-MM-dd hh:mm:ss dddd");//设置系统时间显示格式
       ui->label->setText(str);//在标签上显示时间
}

15 Socket简单通信

1.UDP通信

UDP没有特定的Server端和Client端,简单来说就是向特定的ip发送报文,因此我把它分为发送端和接收端。

注意:在.pro文件中要添加:

QT += network

否则无法使用Qt的网络功能。

1.1.UDP发送端(Client)

    #include <QtNetwork>
    QUdpSocket *sender;
    sender = new QUdpSocket(this);
    QString datagramString="hello world!异想家";
    QByteArray datagram = datagramString.toLocal8Bit();//fromLocal8Bit解决中文乱码
    //sender->writeDatagram(datagram.data(),datagram.size(),QHostAddress::Broadcast,1994);//UDP广播
    QHostAddress serverAddress = QHostAddress("127.0.0.1");//向特定IP发送
    sender->writeDatagram(datagram.data(), datagram.size(),serverAddress, 1994);

1.2.UDP接收端(Server)

打开 MainWindow.h 文件编写如下代码。

include

private:
    QUdpSocket *receiver;
private slots:
    void readPendingDatagrams(); //UDPS信号槽

打开 MainWindow.cpp 文件编写如下代码。

void MainWindow::on_pushButton_UDPS_clicked()
{

    receiver = new QUdpSocket(this);
    receiver->bind(QHostAddress::LocalHost, 1995);//端口号设置
    connect(receiver, SIGNAL(readyRead()),this, SLOT(readPendingDatagrams()));

}

void MainWindow::readPendingDatagrams()
{
    while (receiver->hasPendingDatagrams())
    {
        QByteArray datagram;
        datagram.resize(receiver->pendingDatagramSize());
        receiver->readDatagram(datagram.data(), datagram.size()); //数据接收在datagram里
        QString DatagramString=QString::fromLocal8Bit(datagram);//fromLocal8Bit解决中文乱码
        ui->textEdit->setText(DatagramString);
    }
}

2.TCP通信

TCP的话要复杂点,必须先建立连接才能传输数据,分为Server端和Client端。

2.1.TCP Client端

#include <QtNetwork>

QTcpSocket *client;
char *data="hello qt!";
client = new QTcpSocket(this);
client->connectToHost(QHostAddress("127.0.0.1"), 1996);
client->write(data);

2.2.TCP Server端

打开 MainWindow.h 文件编写如下代码。

#include <QtNetwork>
private:
    QTcpServer *server;
    QTcpSocket *clientConnection;
private slots:
    void acceptConnection();
    void readClient();

打开 MainWindow.cpp 文件编写如下代码。

void MainWindow::on_pushButton_TCPS_clicked()
{
server = new QTcpServer();
server->listen(QHostAddress::Any, 1997);
connect(server, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
}

//TCP接受连接
void MainWindow::acceptConnection()
{
    clientConnection = server->nextPendingConnection();
    connect(clientConnection, SIGNAL(readyRead()), this, SLOT(readClient()));
}

//TCP收
void MainWindow::readClient()
{
    QString str = clientConnection->readAll();
    //或者
    //char buf[1024];
    //clientConnection->read(buf,1024);
    ui->textEdit->setText(str);
}

16 组件应用

【9.1 日历组件】
打开 MainWindow.h 文件编写如下代码。

include

include

include

private slots:

void showTime();
void setData();

private:

QLabel *label;
QLineEdit * lineEdit;
QCalendarWidget *calendarWidget;

打开 MainWindow.cpp 文件编写如下代码。
label = new QLabel(this);//实例 QLabel 控件
label->setText("选择日期:");
label->setGeometry(QRect(50,50,100,25));//位置

lineEdit = new QLineEdit(this);
lineEdit->setGeometry(QRect(110,50,150,22));
connect(lineEdit,SIGNAL(cursorPositionChanged(int,int)),this,SLOT(showTime()));//事件

calendarWidget = new QCalendarWidget(this);//实例时间控件
calendarWidget->setGeometry(20,75,350,180);//位置
calendarWidget->setHidden(true);//隐藏时间控件
connect(calendarWidget,SIGNAL(clicked(QDate)),this,SLOT(setData()));//时间控件点击事件

void MainWindow::showTime()
{

calendarWidget->setHidden(false);

}

void MainWindow::setData()
{

QDate date = calendarWidget->selectedDate();//接收选择时间
QString str = date.toString("yyyy-MM-dd");//时间格式化
lineEdit->setText(str);//赋值
calendarWidget->setHidden(true);//日期控件隐藏

}

【9.2 登录窗口】
说明:这里需要注意在创建项目时:基类选择:QWidget 类,不选 QMainWindow 类。
打开 MainWindow.h 文件编写如下代码:

include

include

include

include

include

include

include

private:

QLineEdit *usrLineEdit;
QLineEdit *pwdLineEdit;
QLabel *usrLabel;
QLabel *pwdLabel;
QGridLayout *gridlayout;
QPushButton *okBtn;
QPushButton *cancelBtn;
QVBoxLayout *vboxLayout;

public slots:

virtual void accept();

打开 MainWindow.cpp 文件编写如下代码。

setMinimumSize(280,150);//窗体最小宽度高度
setMaximumSize(280,150);//窗体最大宽度高度
//实例用户名密码控件
usrLabel = new QLabel(tr("用户名:"));
pwdLabel = new QLabel(tr("密 码:"));
usrLineEdit = new QLineEdit;
pwdLineEdit = new QLineEdit;
pwdLineEdit->setEchoMode(QLineEdit::Password);//密码*号输入
usrLineEdit->setMaxLength(12);//限制输入 12 位
pwdLineEdit->setMaxLength(12);

gridlayout = new QGridLayout;//实例网格布局控件
gridlayout->addWidget(usrLabel,0,0,1,1);//添加布局 0,0,1,1 行 列 行间距 列间距
gridlayout->addWidget(usrLineEdit,0,1,1,1);
gridlayout->setSpacing(20);//间隔
gridlayout->addWidget(pwdLabel,1,0,1,1);
gridlayout->addWidget(pwdLineEdit,1,1,1,1);

//实例按钮控件
okBtn = new QPushButton(tr("确定"));
cancelBtn = new QPushButton(tr("取消"));
connect(okBtn,SIGNAL(clicked()),this,SLOT(accept()));
connect(cancelBtn,SIGNAL(clicked()),this,SLOT(reject()));

QHBoxLayout *hboxLayout = new QHBoxLayout;
hboxLayout->setSpacing(60);//横向布局填充控件
hboxLayout->addWidget(okBtn);
hboxLayout->addWidget(cancelBtn);

vboxLayout = new QVBoxLayout;//实例纵向布局填充刚刚实例的两个布局
vboxLayout->addLayout(gridlayout);
vboxLayout->addLayout(hboxLayout);
this->setLayout(vboxLayout);//显示内容

//确定方法
void Dialog::accept()
{

if(usrLineEdit->text().trimmed() == "admin" && pwdLineEdit->text().trimmed() == "admin")
{
    QDialog::accept();
}else
{
    QMessageBox::warning(this,"警告","用户名或密码错误!!!",QMessageBox::Yes);
    usrLineEdit->setFocus();
}

}

【9.3 文件浏览对话框】
打开 MainWindow.h 文件编写如下代码。

include //单行文本控件类

include //按钮类

private:

QLineEdit *filename;
QPushButton *button;

private slots:

void showFiles();

打开 MainWindow.cpp 文件编写如下代码。

include //引用文件浏览对话框类

filename = new QLineEdit(this);//实例单行文本控件
filename->setGeometry(QRect(50,50,230,25));//位置
button = new QPushButton(this);//实例按钮
button->setGeometry(QRect(280,50,80,25));//按钮位置
button->setText("浏览");//按钮名
connect(button,SIGNAL(clicked()),this,SLOT(showFiles()));//按钮点击事件

//按钮点击方法
void MainWindow::showFiles()
{

//定义变量 str 接收 QFileDialog 对话框获取的文件路径
QString str = QFileDialog::getOpenFileName(this,"open file","/","textfile(*.txt);;C file(*.cpp);;All file(*.*)");
//将变量绑定 QLineEdit 控件
filename->setText(str.toUtf8());

}

【9.4 进度条实例】

打开 MainWindow.h 文件编写如下代码。

include //按钮类

include //进度条类

private:

QPushButton *button;
QProgressBar *bar;

private slots:

void startBar();

打开 MainWindow.cpp 文件编写如下代码。

bar = new QProgressBar(this);//实例 QProgressBar 控件
bar->setGeometry(QRect(50,50,200,20));//位置
bar->setRange(0,100000-1);//范围值
bar->setValue(0);//初始值

button = new QPushButton(this);//实例 Button
button->setGeometry(QRect(270,50,80,25));//位置
button->setText("开始");//值
connect(button,SIGNAL(clicked()),this,SLOT(startBar()));//事件

void MainWindow::startBar()
{

for(int i=0;i<100000;i++)
{
    //100%结束
    if(i == 99999)
    {
        button->setText("结束");
    }
    //赋值
    bar->setValue(i);
}

}

【9.5 Timer实时更新时间】
打开 MainWindow.h 文件编写如下代码。

include

include

private:

QLabel *label;
QTimer *timer;

private slots:

void timerTime();

打开 MainWindow.cpp 文件编写如下代码。

include

label = new QLabel(this);//实例 QLabel 控件
label->setGeometry(QRect(50,50,200,25));//位置

timer = new QTimer;//实例 QTimer 控件
connect(timer,SIGNAL(timeout()),this,SLOT(timerTime()));//timer 时间
timer->start(1000);//执行

void MainWindow::timerTime()
{

QDateTime sysTime = QDateTime::currentDateTime();//获取系统时间
label->setText(sysTime.toString());

}

【10 图形图像操作】
【10.1 绘制文字】
打开 MainWindow.cpp 文件编写如下代码

include

include

//实例 QGraphicsScene
QGraphicsScene *scene = new QGraphicsScene;
//背景色
scene->setForegroundBrush(QColor(0, 255, 255, 127));
//字体设置
QFont font("微软雅黑",60);
//添加文字
scene->addSimpleText("异想家Sandeepin",font);
//网格
//scene->setForegroundBrush(QBrush(Qt::lightGray, Qt::CrossPattern));
//实例 QGraphicsView
QGraphicsView *view = new QGraphicsView(scene);
//显示
this->setCentralWidget(view);

【10.2 绘制线条】
打开 MainWindow.cpp 文件编写如下代码。

include

include

//实例 QGraphicsScene
QGraphicsScene *scene = new QGraphicsScene;
//QPen 属性
QPen pen;
pen.setStyle(Qt::DashDotLine);
pen.setWidth(2);
pen.setBrush(Qt::black);
pen.setCapStyle(Qt::RoundCap);
pen.setJoinStyle(Qt::RoundJoin);
//绘制线条
scene->addLine(30,30,200,30,pen);
//实例 QGraphicsView
QGraphicsView *view = new QGraphicsView(scene);
//显示
this->setCentralWidget(view);

【10.3 绘制椭圆】
打开 MainWindow.cpp 文件编写如下代码。

include

include

//实例 QGraphicsScene
QGraphicsScene *scene = new QGraphicsScene;
//绘制椭圆
scene->addEllipse(50,50,100,120);
//实例 QGraphicsView
QGraphicsView *view = new QGraphicsView(scene);
//显示
this->setCentralWidget(view);

【10.4 显示静态图像】
打开 MainWindow.h 文件编写如下代码。
protected:

void paintEvent(QPaintEvent *);

打开 MainWindow.cpp 文件编写如下代码。

include

// 当调用update(),repaint()的时候,paintEvent()会被调用,当界面有任何改变的时候,paintEvent()也会被调用
void MainWindow::paintEvent(QPaintEvent *)
{

//实例 QPixmap
QPixmap image(":/new/prefix1/poi");
 //实例 QPainter 绘制类
QPainter painter(this);
//绘制图片
painter.drawPixmap(20,20,310,310,image);

}

【10.5 显示动态图像】
打开 MainWindow.cpp 文件编写如下代码。

include

include

include

//实例 QLabel
QLabel *label = new QLabel(this);
label->setGeometry(QRect(50,50,130,130));
//实例 QMovie
QMovie *movie = new QMovie(":/new/prefix1/jfz");
//3 秒后图片消失
QTimer::singleShot( 3*1000, label, SLOT(close())); // 三秒关闭标签,等于关闭图片
label->setMovie(movie); // 标签中放movie
movie->start();

【10.6 图片水平移动】
打开 MainWindow.h 文件编写如下代码。

include

include

include

private:

QLabel *label;
QImage *img;
QPushButton *button;

private slots:

void moveImg();

打开 MainWindow.cpp 文件编写如下代码。
//实例 QLabel
label = new QLabel(this);
label->setGeometry(QRect(50,50,310,310));
//实例 QImage
img = new QImage;
//QImage 加载图片
img->load(":/new/prefix1/poi");
//label 显示图片
label->setPixmap(QPixmap::fromImage(*img));
//实例 button
button = new QPushButton(this);
button->setGeometry(QRect(50,150,80,25));
button->setText("移动");
connect(button,SIGNAL(clicked()),this,SLOT(moveImg()));

//点击移动
int i = 50;
void MainWindow::moveImg()
{

//移动 label 控件
label->move(i,50);
i += 10;

}

【10.7 图片翻转】
打开 MainWindow.h 文件编写如下代码。

include

include

include

private:

QLabel *label;
QImage *img;
QPushButton *hBt;
QPushButton *vBt;
QPushButton *angleBt;

private slots:

void hShow();
void vShow();
void angleShow();

打开 MainWindow.cpp 文件编写如下代码。

include

//实例 QLabel
label = new QLabel(this);
label->setGeometry(QRect(160,50,310,310));
//实例 QImage
img = new QImage;
//QImage 加载图片
img->load(":/new/prefix1/poi");
//label 显示图片
label->setPixmap(QPixmap::fromImage(*img));
//实例水平操作按钮
hBt = new QPushButton(this);
hBt->setGeometry(QRect(50,200,80,25));
hBt->setText("水平翻转");
connect(hBt,SIGNAL(clicked()),this,SLOT(hShow()));
//实例垂直操作按钮
vBt = new QPushButton(this);
vBt->setGeometry(QRect(160,200,80,25));
vBt->setText("垂直操作");
connect(vBt,SIGNAL(clicked()),this,SLOT(vShow()));
//实例角度操作按钮 88°
angleBt = new QPushButton(this);
angleBt->setGeometry(QRect(270,200,80,25));
angleBt->setText("角度操作");
connect(angleBt,SIGNAL(clicked()),this,SLOT(angleShow()));

//水平操作
void MainWindow::hShow()
{

//水平翻转
*img = img->mirrored(true,false);
//显示图片
label->setPixmap(QPixmap::fromImage(*img));

}
//垂直操作
void MainWindow::vShow()
{

//垂直翻转
*img = img->mirrored(false,true);
//显示图片
label->setPixmap(QPixmap::fromImage(*img));

}
//角度操作
void MainWindow::angleShow()
{

QMatrix matrix;
//88 度角
matrix.rotate(88);
*img = img->transformed(matrix);
label->setPixmap(QPixmap::fromImage(*img));

}

【10.8 图片缩放】
打开 MainWindow.h 文件编写如下代码。

include

include

include

private:

QLabel *label;
QImage *img;
QPushButton *bigBt;
QPushButton *smallBt;

private slots:

void bShow();
void sShow();

打开 MainWindow.cpp 文件编写如下代码。
//实例 QLabel
label = new QLabel(this);
label->setGeometry(QRect(50,50,400,400));
//实例 QImage
img = new QImage;
//QImage 加载图片
img->load(":/new/prefix1/poi");
//label 显示图片
label->setPixmap(QPixmap::fromImage(*img));
//实例放大按钮
bigBt = new QPushButton(this);
bigBt->setGeometry(QRect(50,350,80,25));
bigBt->setText("放大");
connect(bigBt,SIGNAL(clicked()),this,SLOT(bShow()));
//实例缩小按钮
smallBt = new QPushButton(this);
smallBt->setGeometry(QRect(260,350,80,25));
smallBt->setText("缩小");
connect(smallBt,SIGNAL(clicked()),this,SLOT(sShow()));

//放大操作
void MainWindow::bShow()
{

*img = img->scaled(400,400,Qt::IgnoreAspectRatio);
label->setPixmap(QPixmap::fromImage(*img));

}
//缩小操作
void MainWindow::sShow()
{

*img = img->scaled(100,100,Qt::IgnoreAspectRatio);
label->setPixmap(QPixmap::fromImage(*img));

}

【10.9 图片中加文字】
打开 MainWindow.cpp 文件编写如下代码。

include

include

include

//实例 QLabel
QLabel *label = new QLabel(this);
label->setGeometry(QRect(50,50,300,25));
label->setText("图片已经生成,保存在项目文件中【text.jpg】。");
//实例 QImage
QImage image = QPixmap(":/new/prefix1/poi").toImage();
//实例 QPainter
QPainter painter(&image);
//设置画刷模式
painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
//改变画笔和字体
QPen pen = painter.pen();
pen.setColor(Qt::red);
QFont font = painter.font();
font.setBold(true);//加粗
font.setPixelSize(50);//改变字体大小
painter.setPen(pen);
painter.setFont(font);
//将文字绘制在图片中心位置
painter.drawText(image.rect(),Qt::AlignCenter,"异想家");
//这个为图片的压缩度。0/100
int n = 100;
//保存图片
image.save("text.jpg","JPG",n);

【10.10 图像扭曲】
打开 MainWindow.h 文件编写如下代码。
protected:

void paintEvent(QPaintEvent *);

打开 MainWindow.cpp 文件编写如下代码

include

void MainWindow::paintEvent(QPaintEvent *)
{

//实例 QPainter
QPainter painter(this);
//实例 QPixmap
QPixmap pix;
//加载图片
pix.load(":/new/prefix1/poi");
//原图显示
painter.drawPixmap(0,50,310,310,pix);
//扭曲
painter.shear(0.5,0); //横向扭曲
//绘制扭曲图
painter.drawPixmap(290,50,310,310,pix);

}

【10.11 模糊效果】
打开 MainWindow.cpp 文件编写如下代码。

include

include

//实例 QLabel
QLabel *label = new QLabel(this);
//QLabel 位置
label->setGeometry(QRect(50,50,310,310));
//实例 QImage
QImage *img = new QImage;
//加载图片
img->load(":/new/prefix1/poi");
label->setPixmap(QPixmap::fromImage(*img));
//实例 QGraphicsBlurEffect
QGraphicsBlurEffect *effect = new QGraphicsBlurEffect(this);
//模糊值,值越大越模糊
effect->setBlurRadius(5);
label->setGraphicsEffect(effect);

【10.12 着色效果】
打开 MainWindow.cpp 文件编写如下代码。

include

include

//实例 QLabel
QLabel *label = new QLabel(this);
//QLabel 位置
label->setGeometry(QRect(50,50,310,310));
//实例 QImage
QImage *img = new QImage;
//加载图片
img->load(":/new/prefix1/poi");
label->setPixmap(QPixmap::fromImage(*img));
//实例 QGraphicsColorizeEffect
QGraphicsColorizeEffect *effect = new QGraphicsColorizeEffect(this);
//设定颜色
effect->setColor(QColor(0,0,192));
label->setGraphicsEffect(effect);

【10.13 阴影效果】
打开 MainWindow.cpp 文件编写如下代码。

include

include

//实例 QLabel
QLabel *label = new QLabel(this);
//QLabel 位置
label->setGeometry(QRect(50,50,310,310));
//实例 QImage
QImage *img = new QImage;
//加载图片
img->load(":/new/prefix1/poi");
label->setPixmap(QPixmap::fromImage(*img));
//实例 QGraphicsDropShadowEffect
QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect(this);
//设定阴影
effect->setOffset(8,8);
label->setGraphicsEffect(effect);

【10.14 透明效果】
打开 MainWindow.cpp 文件编写如下代码。

include

include

//实例 QLabel
QLabel *label = new QLabel(this);
//QLabel 位置
label->setGeometry(QRect(50,50,310,310));
//实例 QImage
QImage *img = new QImage;
//加载图片
img->load(":/new/prefix1/poi");
label->setPixmap(QPixmap::fromImage(*img));
//实例 QGraphicsOpacityEffect
QGraphicsOpacityEffect *effect = new QGraphicsOpacityEffect(this);
//设定透明值
effect->setOpacity(0.5);
label->setGraphicsEffect(effect);

【11 多媒体应用】
【11.1 音频、视频播放器】
打开 QtMovieStudy.pro 工程文件编写如下代码。
QT+=axcontainer

打开 mainwindow.h 文件编写如下代码。

include

include

include

include

// Q_ENUMS()宏的参数是枚举类型。对枚举对象进行反射(reflection)
Q_ENUMS(ReadyStateConstants)
//播放状态 枚举类型
enum PlayStateConstants{Stopped = 0, Paused = 1, Playing = 2};
enum ReadyStateConstants{Uninitialized = 0, Loading = 1, Interactive = 3, Complete = 4};

//播放进度
protected:

void timerEvent(QTimerEvent *event);

private:

QAxWidget   *axWidget;        //播放器
QToolButton *openButton;      //浏览按钮
QToolButton *playPauseButton; //暂停播放按钮
QToolButton *stopButton;      //停止播放按钮
QSlider     *seekSlider;      //进度条
QString     fileFilters;      //文件格式
int         updateTimer;      //播放进度
QWidget     *widget;          //QWidget

private slots:

void onPlayStateChange(int oldState, int newState);      // 播放状态(暂停\播放...)
void onReadyStateChange(ReadyStateConstants readyState); // 准备状态
void onPositionChange(double oldPos, double newPos);
void sliderValueChanged(int newValue);
void openFile();

打开 mainwindow.cpp 文件编写如下代码。

include

include

include

//实例 QAxWidget(播放器插件)
axWidget = new QAxWidget;
//注册表键值,调用插件
axWidget->setControl("{22D6F312-B0F6-11D0-94AB-0080C74C7E95}");  // WMP v6.4的ClassID
axWidget->setProperty("ShowControls", false);
axWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
connect(axWidget, SIGNAL(PlayStateChange(int, int)),this, SLOT(onPlayStateChange(int, int)));
connect(axWidget, SIGNAL(ReadyStateChange(ReadyStateConstants)),this, SLOT(onReadyStateChange(ReadyStateConstants)));
connect(axWidget, SIGNAL(PositionChange(double, double)),this, SLOT(onPositionChange(double, double)));
//实例打开文件按钮
openButton = new QToolButton;
openButton->setText(tr("浏览.."));
connect(openButton, SIGNAL(clicked()), this, SLOT(openFile()));
//实例播放暂停按钮
playPauseButton = new QToolButton;
playPauseButton->setText(tr("播放"));
playPauseButton->setEnabled(false);
connect(playPauseButton, SIGNAL(clicked()), axWidget, SLOT(Play()));
//停止按钮
stopButton = new QToolButton;
stopButton->setText(tr("停止"));
stopButton->setEnabled(false);
connect(stopButton, SIGNAL(clicked()), axWidget, SLOT(Stop()));
//进度条
seekSlider = new QSlider(Qt::Horizontal);
seekSlider->setEnabled(false);
connect(seekSlider, SIGNAL(valueChanged(int)),this, SLOT(sliderValueChanged(int)));
connect(seekSlider, SIGNAL(sliderPressed()),axWidget, SLOT(Pause()));
//可播放格式,此处简写下面几个
fileFilters = tr("Video files (*.mpg *.mpeg *.avi *.wmv *.mp4)\n" "Audio files (*.mp3 *.wav)");
//初始化播放时间进度
updateTimer = 0;
//三个按钮横向布局
QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addWidget(openButton);
buttonLayout->addWidget(playPauseButton);
buttonLayout->addWidget(stopButton);
//纵向布局,上面播放器下面三个按钮
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(axWidget);
mainLayout->addLayout(buttonLayout);
mainLayout->addWidget(seekSlider);
//显示布局控件
widget = new QWidget();
widget->setLayout(mainLayout);
this->setCentralWidget(widget);

//选择音视频文件
void MainWindow::openFile()
{

//定义 QString 变量接收文件
QString fileName = QFileDialog::getOpenFileName(this,tr("Select File"), ".", fileFilters);
//如果文件不为空,则播放
if (!fileName.isEmpty())
    axWidget->setProperty("FileName",QDir::toNativeSeparators(fileName));

}

//进度条随播放器移动
void MainWindow::timerEvent(QTimerEvent *event)
{

if (event->timerId() == updateTimer)
{
    double curPos = axWidget->property("CurrentPosition").toDouble();
    onPositionChange(-1, curPos);
}
else
{
    QWidget::timerEvent(event);
}

}

void MainWindow::onPlayStateChange(int, int newState)
{

playPauseButton->disconnect(axWidget);
switch (newState)
{
    case Stopped:
        if (updateTimer)
        {
            killTimer(updateTimer);
            updateTimer = 0;
        }
    case Paused:
        connect(playPauseButton, SIGNAL(clicked()), axWidget, SLOT(Play()));
        stopButton->setEnabled(false);
        playPauseButton->setText(tr("播放"));
        break;
    case Playing:
        if (!updateTimer)
            updateTimer = startTimer(100);
        connect(playPauseButton, SIGNAL(clicked()),axWidget, SLOT(Pause()));
        stopButton->setEnabled(true);
        playPauseButton->setText(tr("暂停"));
}

}

void MainWindow::onReadyStateChange(ReadyStateConstants ready)
{

if (ready == Complete)
{
    double duration = 60 * axWidget->property("Duration").toDouble();
    seekSlider->setMinimum(0);
    seekSlider->setMaximum(int(duration));
    seekSlider->setEnabled(true);
    playPauseButton->setEnabled(true);
}

}

void MainWindow::onPositionChange(double, double newPos)
{

seekSlider->blockSignals(true);
seekSlider->setValue(int(newPos * 60));
seekSlider->blockSignals(false);

}

void MainWindow::sliderValueChanged(int newValue)
{

seekSlider->blockSignals(true);
axWidget->setProperty("CurrentPosition", double(newValue) / 60);
seekSlider->blockSignals(false);

}

【11.1.2】简易播放mp3
pro文件:
QT += multimedia

头文件:

include

cpp代码:
player = new QMediaPlayer;
connect(player, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64)));
player->setMedia(QUrl::fromLocalFile("SovietMarch.mp3"));
player->setVolume(30);
player->play();

【11.2 播放 Flash 动画】
打开 Qt02.pro 工程文件编写如下代码。
QT+=axcontainer

打开 mainwindow.cpp 文件编写如下代码。

include

include

include

include

//实例 QAxWidget
QAxWidget *flash = new QAxWidget(0,0);
//显示大小
flash->resize(460,370); //设置该空间的初始大小
//设置注册表键值,调用 ActiveX 插件
flash->setControl(QString::fromUtf8("{d27cdb6e-ae6d-11cf-96b8-444553540000}"));
//设定控制器
//文件路径,注意如果发布可执行文件,播放文字路径需要拷贝一份
flash->dynamicCall("LoadMovie(long,string)",0,QDir::currentPath()+"/jfz.swf");
//纵向布局
QVBoxLayout *layout = new QVBoxLayout;
//布局填充 QAxWidget
layout->addWidget(flash);
//实例 QWidget
QWidget *widget = new QWidget();
widget->setLayout(layout);
//界面显示
this->setCentralWidget(widget);
//界面标题为路径注意查看路径。
this->setWindowTitle(QDir::currentPath());

【11.3 播放图片动画】
打开 mainwindow.h 工程文件编写如下代码。

include

include

include

private:

QPixmap *pm;
QLabel *label;
QTimer *timer;
int i;

private slots:

void changeImg();

打开 mainwindow.cpp 工程文件编写如下代码。
//实例 QPixmap
pm = new QPixmap;
//加载第一张图片
pm->load(":/image/a0");
//实例 QLabel
label = new QLabel(this);
//位置
label->setGeometry(QRect(50,50,150,150));
//Label 加载 QPixmap
label->setPixmap(*pm);
//实例 QTimer
timer = new QTimer;
//事件
connect(timer,SIGNAL(timeout()),this,SLOT(changeImg()));
//启动 QTimer
timer->start(100);
//初始值
i = -1;

void MainWindow::changeImg()
{

//i 不可大于 3,因为只准备了 3 张图片,i 从 0 开始。
if(i < 3)
{
    //每次 QTimer 执行 i+1;
    i++;
    //资源文件图片变量
    QString str = ":/image/a";
    //qDebug(str.toUtf8().append(QString::number(i,10)));
    //加载图片路径
    pm->load(str.toUtf8().append(QString::number(i,10)));
    //QLabel 显示图片
    label->setPixmap(*pm);
}else
{
    //循环一圈后,回到初始值,继续执行。
    i = -1;
}

}

【12 数据库基础】
【12.1 查询数据库驱动】
打开 Qt01.pro 工程文件编写如下代码。
QT += sql //否则找不到

打开 mainwindow.cpp 文件编写如下代码。

include <QtSql/QSqlDatabase>

include

include

//实例 QStringList 接收驱动信息
QStringList drivers = QSqlDatabase::drivers();
//循环输出
foreach(QString driver, drivers)
{
qDebug() << "r" << driver;
}

在Qt5.6我的电脑上输出:
"QSQLITE"
"QMYSQL"
"QMYSQL3"
"QODBC"
"QODBC3"
"QPSQL"
"QPSQL7"

【12.2 操作 SQLite 数据库】
打开 Qt05.pro 工程文件编写如下代码。
QT += sql

打开 mainwindow.h 文件编写如下代码。

include <QtSql/QSqlDatabase>

//测试连接
bool connection();
//创建数据库
void createDB();
QSqlDatabase db;
//绑定数据
void bindData();

打开 mainwindow.cpp 文件编写如下代码。

include <QtSql/QSqlDatabase>

include

include

include

include

include

//实例 QLabel
QLabel *label = new QLabel(this);
label->setGeometry(QRect(50,50,200,25));
//注意数据库路径
this->setWindowTitle(QDir::currentPath());
//判断数据库文件是否存在
bool dbFile = !QFile::exists(QDir::currentPath()+"/db.db");
if(connection())
{

label->setText("连接成功");
//打开数据库,判断是否连接成功
if(dbFile)
{
    label->setText("不存在创建");
    //创建
    createDB();
    //绑定数据
    bindData();
}
else
{
    //label->setText("存在");
    //绑定数据
    bindData();
}
//关闭数据库
db.close();

}
else
{

label->setText("连接失败");

}

//测试连接
bool MainWindow::connection()
{

//实例 QSqlDatabase
db = QSqlDatabase::addDatabase("QSQLITE");
//数据库名称
db.setDatabaseName("db.db");
//判断是否可以打开
if(!db.open())
{
    return false;
}
return true;

}

//创建数据库
void MainWindow::createDB()
{

//实例 QSqlQuery
QSqlQuery query;
//用 SQL 命令创建表
//表名:person
//id:自增,主键
//name:存人名称
//time:时间自动添加
query.exec("CREATE TABLE person ("
           "id INTEGER PRIMARY KEY AUTOINCREMENT, "
           "name VARCHAR(50) NOT NULL, "
           "time TIMESTAMP default CURRENT_TIMESTAMP)");
//插入数据
query.exec("INSERT INTO person (name) VALUES ('异想家')");
query.exec("INSERT INTO person (name) VALUES ('蒋方正')");
query.exec("INSERT INTO person (name) VALUES ('路然真')");

}

//绑定数据
void MainWindow::bindData()
{

//QTableView
QTableView *tableView = new QTableView(this);
tableView->setGeometry(QRect(50,80,400,400));
//实例 QSqlTableModel
QSqlTableModel *model = new QSqlTableModel;
//为数据模型指定表
model->setTable("person");
//查询
model->select();
//填充模型
tableView->setModel(model);
//表格只读,默认单元格可修改
tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);

}

【12.3 】Qt线程
以计算为主的运算密集型线程数量理论上只要为CPU核心数量即可,如使用线程计算质数组合解析数据等。
以等待为主的IO密集型线程数量可以按照具体业务规模适当增加线程,如使用线程读写数据库、硬盘、远程接口获取数据等(具体项目中可以增加的线程而不影响运行效率的阀值需要不同项目具体测试得出)

Qt中如何创建使用线程,非常简单,只需要继分为三步:

创建线程类,继承QThread
重写run()
主线程中创建线程对象,使用start()方法启动线程。
(一)首先,新建Qt命令行项目,在项目中创建线程类CSimpleThread.h:

ifndef CSIMPLETHREAD_H

define CSIMPLETHREAD_H

include

class CSimpleThread : public QThread
{

Q_OBJECT

public:

CSimpleThread();

};

endif // CSIMPLETHREAD_H

CSimpleThread.cpp:

include "CSimpleThread.h"

include

CSimpleThread::CSimpleThread()
{

}

(二)重写run(),每5秒打印一句话

CSimpleThread.h

ifndef CSIMPLETHREAD_H

define CSIMPLETHREAD_H

include

class CSimpleThread : public QThread
{

Q_OBJECT

public:

CSimpleThread();
void run();

};

endif // CSIMPLETHREAD_H

CSimpleThread.cpp

include "CSimpleThread.h"

include

CSimpleThread::CSimpleThread()
{

}

void CSimpleThread::run()
{

while (true) {
    qDebug()<<"CSimpleThread run!";
    sleep(5);
}

}

(三)主线程中创建线程对象,使用start()方法启动线程。

main.cpp

include

include <CSimpleThread.h>

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

QCoreApplication a(argc, argv);

CSimpleThread *SThread = new CSimpleThread();
SThread->start();

return a.exec();

}

文章目录