Qt图形框架

Qt图形框架

环境准备

  1. 安装Ubuntu虚拟机并配置远程

    1. 安装完系统后安装Xrdp
        sudo apt-get update
        sudo apt-get xrdp
        sudo systemctl status xrdp
      
  2. 设置root可以远程桌面登录

       # 允许root用户远程ssh登录
       sudo sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config
       # 允许使用密码连接ssh服务
       sudo sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config
       # 重启ssh服务
       sudo service sshd restart
       sudo su - root
       passwd root 
       #设置root密码
       确认密码
       restart
    
  3. 测试连接
    在这里插入图片描述
    在这里插入图片描述



一、 Qt的概述

Qt(跨平台的C++ GUI应用程序开发框架)
常见:
1)控件类:QT += widgets

类名 功能
QApplication Qt的gui应用程序
QWidget 控件基类
QLabel 标签
QPushButton 按钮
QDialog 对话框
QMainWindow 主窗口
QSlider 滑块
QSpinBox 选值框
QLineEdit 行编辑
QFrame 显示框架
QMessageBox 消息提示框
QListWidget 列表窗口
QTableView 表格视图
QLayout 布局器
QSpacerItem 间隔器

2)Qt核心类:QT += core gui

类名 功能
QObject 最顶层的基类
QString 字符串
QTextCodec 字符编码
QPainter 画家类
QImage 图片
QRect 矩形区域
QPoint 位置
QSize 大小
QDir 目录
QTime 时间
QTimer 定时器
QPaintEvent 绘图事件
QTimerEvent 定时器事件
QMouseEvent 鼠标事件
QKeyEvent 键盘事件

3)Qt数据库 QT += sql

类名 功能
QSqlDatabase 建立Qt和数据库连接
QSqlQuery 执行SQL语句
QSqlQueryModel 保存查询结果集

4)Qt网络编程 QT += network

类名 功能
QAbstractSocket 套接字基类
QTcpServer TCP服务器
QTcpSocket TCP套接字
QUdpSocket UDP套接字
QHostAddress IP地址

1. Qt发展历史

  • 1991年诞生,Haavard Nord和Eirik Chambe-Eng合作编写最初的Qt
  • 1994年Haavard Nord和Eirik Chambe-Eng创立奇趣科技(Trolltech)公司
  • 2005年Qt4.0发布
  • 2008年奇趣科技公司被诺基亚收购
  • 2009年Qt源代码开放
  • 2012年诺基亚将Qt业务和全部知识产权出售给Digia公司
  • 2013年Qt5.0发布
  • 2014年Digia成立子公司The Qt Company

2. Qt5.4安装和配置

  1. 官网安装教程:https://resources.qt.io/learning-hub/introduction-to-qt-installing-qt-creator

  2. 注:根据提示,默认安装在主目录下,选择一个版本安装就可以
    在这里插入图片描述

  3. 配置环境变量
    1)sudo vim /etc/profile
    最后插入这二行
    export PATH= P A T H : / h o m e / q t / Q t / 6.2.3 / g c c 6 4 / b i n e x p o r t P A T H = PATH:/home/qt/Qt/6.2.3/gcc_64/bin export PATH= PATH:/home/qt/Qt/6.2.3/gcc64/binexportPATH=PATH:/home/qt/Qt/Tools/QtCreator/bin

    2)修改用户加载
    vim ~/.bashrc // 有些系统是 .bash 文件名
    最后一行添加 source /etc/profile

  4. 重启系统测试
    执行“qmake -v”正常看到Qt的版本信息
    执行“qtcreator”正常可以进入Qt的集成开发环境界面

    问题:提示缺少libgstreamer…相关库
    解决:在线安装

       sudo apt-get install libgstreamer0.10-0
       sudo apt-get install libgstreamer-plugins-base0.10-0
    

    问题:编译Qt程序时提示缺少libgl…相关库(没有安装openGL)
    解决:在线安装

      sudo apt-get install libgl1-mesa-devs
    


3. Qt相关的工具介绍

  • Qt助手(assistant) //Qt帮助手册
  • Qt构建器(qmake) //构建Qt应用程序
  • Qt设计师(designer) //图形界面编辑器
  • Qt界面编译器(uic) //将设计师得到xml(.ui)文件转换为C++文件(.h)
  • Qt元对象编译器(moc) //将Qt中语法扩展还原为标准C++代码
  • Qt资源编译器(rcc) //将图片资源转换为C++文件(.cpp)
  • Qt创造器(qtcreator) //Qt的集成开发环境(IDE),包含上面所有工具

4. Qt助手的使用

eg:QApplication/QLabel

  • 先看第一句话,了解该类的功能,如果看不懂,可以点击"more"查看详细说明。
  • 接着往下看,了解头文件(和类名一致),构建选项(QT+=widgets),继承关系。
  • 类中成员变量(Properties)
  • 公有的成员函数(Public Functions)
  • 公有的虚函数(Reimplemented Public Functions)
  • 槽函数(Public Slots)//Qt语法扩展
  • 信号函数(Signals)//Qt语法扩展
  • 静态公有成员(Static Public Members)
  • 保护虚函数(Reimplemented Protected Functions)
  • 宏(Macros)
  • 详细说明(Detailed Description)
    练习:看QLabel(标签)帮助手册


二、 第一个Qt程序

  1. 创建工程目录
    mkdir Hello
    注:每个Qt应用程序都应该放在独立的工程目录下

  2. 进入工程目录,编写源代码(c++)
    cd Hello
    vi main.cpp

#include <QApplication>
#include <QLabel> //标签控件

int main(int argc,char** argv){
   
  //构建QT应用程序o
  QApplication app(argc,argv);

  //创建标签控件(图形对象,部件,构件,组件);
 QLabel label("Hello Qt");
  //显示标签控件
  label.show();
  return 0;
}
  1. 执行“qmake -project”,得到工程文件(Hello.pro)
    注意:一般需要添加“QT += widgets”,表示需要用和widgets模块对应的头文件和库文件

  2. 执行“qmake”,根据工程文件得到Makefile

  3. 执行“make”完成编译和链接
    如果没有问题会得到可执行程序"Hello";如果有语法错误,修改源代码再次执行“make”即可,前面3、4步不必重复执行。

  4. 测试运行,可以看到标签窗口
    ./Hello
    练习:创建一个Qt应用程序,里面包含一个QPushButton(按钮),显示文本Button.
    参考代码:

 #include <QApplication>
 #include <QPushButton>
 int main(int argc,char* argv[]){
   
    QApplication app(argc,argv);
   //创建按钮控件
   QPushButton button("Button");
   //显示按钮控件
   button.show();
   return app.exec();
 }

注意:
如果报错找不到 /usr/bin/ld: 找不到 -lGL
执行命令安装包:

    sudo apt-get install libgl1-mesa-dev
 ```
 
<br>
<br>

## 三、 Qt字符串(QString)和字符编码
1. **常见编码**
 1)windows默认使用ANSI(中文gbk编码,英文ACKII)
 2)linux默认使用unicode(utf-8)
 3)Qt字符串QString内部默认使用unicode(utf-16)

2. **编码转换(QTextCodec)**
 //创建GBK编码转换对象
 QTextCodec *codec = QTextCodec::codecForName("GBK");
 //使用编码对象,将参数中文字符串转换为unicode编码字符串
 QString string = codec->toUnicode("GBK编码中文字符串");
 注意:
 使用vi的底行命令可以查看或设置源代码编码方式
 set fileencoding //查看现在设置编码
 set fileencoding=gbk //设置GBK编码(euc-cn,cp936)
 
```c 
#include <QApplication>
#include <QPushButton>
#include <QTextCodec>
int main(int argc,char* argv[]){
   
    QApplication app(argc,argv);

  //1)创建编码转换对象
  QTextCodec* codec = QTextCodec::codecForName("GBK");
  //(2)将要显示的字符串转换为QT内部的unicode编码
  QString str = codec->toUnicode("下午听课有点困");
  //创建按钮控件
  QPushButton button(str);
   //显示按钮控件
   button.show();
   return app.exec();
 }

练习:
创建Qt应用程序对象,里面包含一个标签(QLabel)和一个按钮(QPushButton),标签显示文本“我是标签”,按钮显示文本“我是按钮”:
1)正常构建,6步,结果ok
2)使用vi底行命令,设置编码gbk,再次执行make,结果中文乱码
3)使用QTextCodec实现编码转换,再次执行make,结果又可以正确显示
参考代码:main.cpp 工程目录需要添加 QT+=widgets QT+=core5compat

#include <QApplication>
#include <QLabel>
#include <QTextCodec>
#include <QPushButton>
int main(int argc,char* argv[]){
   
  QApplication app(argc,argv);

  QLabel label("我是标签");
  label.show();
  QPushButton button("我是按钮");
  button.show();

  return app.exec();

 }


三、父窗口(容器窗口)

  1. 常用的父窗口类
    –》QWidget //控件基类
    –》QDialog //对话框,QWidget的子类
    –》QMainWindow //主窗口,QWidget的子类

  2. QWidget中两个常用的函数
    –》调整控件或父窗口位置
    void move(int x,int y);
    –》调整控件或父窗口大小
    void resize(int w,int h);
    注意:
    在Qt中new对象如果指定了父窗口,那么可以不用delete,因为在父窗口对象销毁时会自动将其销毁掉。
    参考代码:main.cpp

#include <QApplication>
#include <QLabel>
#include <QPushButton>
#include <QMainWindow> //主窗口
#include <QDialog> //对话框
#include <QWidget> //控件基类
int main(int argc,char** argv){
   
     QApplication app(argc,argv);
     //创建父窗口
     //QMainWindow parent;
     QDialog parent;  //居中大小均匀
     //QWidget parent;   //靠左上角显示
     
     //创j标签和按钮控件并停靠在父窗口上面
     QLabel label("我是标签",&parent);
     QPushButton button("确认修改",&parent);
   
     //设置父窗口和每个控件大小和位置
     parent.resize(480,320);
     label.move(30,50);
     button.move(220,280);
   
     //显示父窗口,上面停靠的控件也会一起被显示
     parent.show();
     return app.exec();
   }


四、信号和槽机制(Signal&slot)

1. 概念

信号和槽是Qt中自行定义的一种通信机制,实现对象之间的交互,当某个对象发生改变时将会发送信号,该信号可以被其它对象接收,接收以后将执行一个指定的成员函数(槽函数).

2. 定义

  • 包含信号或槽的类必须是QObject的子类
  • 信号使用“signals:”标记,信号函数只需声明,不能写定义
  • 槽使用“public slots:”标记,槽函数可以和某个信号建立连接,通过某个信号触发槽函数的执行;另外槽函数也可以当做是普通的成员函数,直接调用
  • 包含信号或槽的类,前面需要添加宏"Q_OBJECT",将来构建工程时,会调用moc(元对象编译器)将语法扩展的信号或槽还原为标准C++代码.
 class XX:public QObject{
   
     Q_OBJECT           //moc
     signals:
       void sigFunc(void);//信号函数
     public slots:
       void slotFunc(void){
   ...}//槽函数
  };


3. 信号和槽连接

QObject::connect(
const QObject* sender, //信号发送对象,可以是QObject所有子类类型
const char* signal, //要发送的信号函数
const QObject* receiver, //信号接收对象,可以是QObject所有子类类型
const char* method ); //接收信号后要执行的槽函数

注意
SIGNAL(信号函数(参数表)) //将信号函数转换为const char*
SLOT(槽函数(参数表)) //将槽函数转换为const char*

案例
创建一个Qt应用程序,里面包含一个标签和两个控件,实现点击按钮关闭标签。
按钮点击时发送信号:clicked()
实现标签关闭功能的槽:close()
增加一个退出按钮
参考代码:close.cpp

#include <QApplication>
#include <QLabel>
#include <QPushButton>
#include <QDialog>
int main(int argc,char **argv){
   
  QApplication app(argc,argv);
  QDialog parent; //父窗口
  QLabel label("我是一个标签",&parent); //栈对象
  QPushButton *button = new QPushButton("我是一个标签",&parent); //堆对象
  QPushButton *button2 = new QPushButton("退出",&parent); //堆对象关闭按钮
  parent.resize(480,320);//父窗口大小
  label.move(50,50); //标签位置
  button->move(50,200);//按钮位置
  button2->move(240,200);//按钮位置
  parent.show();  //显示父窗口

  //实现点击按钮关闭标签功能
  QObject::connect(button,SIGNAL(clicked(void)),&label,SLOT(close(void)));
  QObject::connect(button2,SIGNAL(clicked(void)),&app,SLOT(closeAllWindows())/*SLOT(quit())*/);

  return app.exec();
}

4. 信号和槽连接的语法要求

  1. 信号和槽参数要一致
    QObject::connect(A,SIGNAL(sigFunc(int)),B,SLOT(slotFunc(int))); //ok
    QObject::connect(A,SIGNAL(sigFunc(void)),B,SLOT(slotFunc(int))); //error

  2. 可以带有缺省参数
    class B{
    Q_OBJECT
    public slots:
    void slotFunc(int i=0){}
    };
    QObject::connect(A,SIGNAL(sigFunc(void)),B,SLOT(slotFunc(void)));//ok

  3. 信号函数的参数可以比槽函数参数多,多余参数将被忽略
    QObject::connect(A,SIGNAL(sigFunc(int)),B,SLOT(slotFunc(void)));//ok

  4. 一个信号可以同时连接多个槽函数(一对多)
    QObject::connect(A,SIGNAL(sigFunc(int)),B1,SLOT(slotFunc1(int)));//ok
    QObject::connect(A,SIGNAL(sigFunc(int)),B2,SLOT(slotFunc2(int)));//ok
    注意:
    如果A对象发送喜好,B1和B2的槽函数都会被执行

  5. 多个信号可以同时连接到同一个槽函数(多对一)
    QObject::connect(A1,SIGNAL(sigFunc1(int)),B,SLOT(slotFunc(int)));//ok
    QObject::connect(A2,SIGNAL(sigFunc2(int)),B,SLOT(slotFunc(int)));//ok
    注意:
    无论A1或A2发送信号,B的槽函数都会被执行

  6. 两个信号函数可以直接连接(信号串联) //了解
    QObject::connect(A1,SIGNAL(sigFunc1(int)),A2,SIGNAL(sigFunc2(int)));//ok
    注意:
    当A1发送信号时,所连接的A2对象的信号也将被发送.
    案例
    创建Qt应用程序,包含一个滑块(QSlider)和选值框(QSpinBox),通过信号和槽的机制,并让它们保持同步运行。
    QSlider //滑块
    void setValue(int)[slot]; //设置当前位置
    void valueChanged(int value)[signal]; //滑块滑动时发送信号
    QSpinBox //选值框
    void setValue(int)[slot]; //设置当前数值
    void valueChanged(int value)[signal]; //选值框数值改变时发送信号
    参考代码:main.cpp

#include <QApplication>
#include <QSlider> //滑块
#include <QSpinBox>  //选值框
#include <QDialog> 
int main(int argc,char **argv){
   
  QApplication app(argc,argv);
  
  QDialog parent; //父窗口
  parent.resize(200,100);

  //创建水平滑块控件并停靠在父窗口上面
  QSlider slider(Qt::Horizontal,&parent);
  slider.move(20,30);
  slider.setRange(0,50); //设置数据变化范围
  //创建选值框控件并停靠在父窗口上面
  QSpinBox spin(&parent);
  spin.move(120,30);
  spin.setRange(0,50); //设置数据变化范围

  //显示父窗口
  parent.show();

  //滑动滑块,选值框随之改变
  QObject::connect(&slider,SIGNAL(valueChanged(int)),&spin,SLOT(setValue(int)));
  //选值框数据改变,滑块随之滑动
  QObject::connect(&spin,SIGNAL(valueChanged(int)),&slider,SLOT(setValue(int)));
  return app.exec();
}


五、面向对象的QT编程

完全不使用任何面向对象技术,而只是利用Qt所提供的类创建对象,并调用对象的接口一满足用户的需求是可能的,但这样构建的QT应用程序其功能必然是
十分有限的:

  • 首先,Qt类保护成员中的诸多实现无法在类的外部被复用,Qt试图通过多态实现的很多机制,如事件处理,完全无法使用
  • 再次,Qt提供的信号和槽不可能满足用户所有的需求,自定义信号和槽需要面向对象技术
  • 最后,Qt设计师,QT创造器等工具链都在以面向对象的方式使用Qt,反其道而行之不会有好结果

案例1:

所谓面向对象的Qt编程就是将C++的面向对象语法特性和Qt图形框架相结合,这里通过面向对象的编程思想实现一个加法计算器案例

  • 输入两个数字,按‘=’按钮显示就算结果
  • 两个操作数必须都是合法的数字,拒绝接受任何非法字符
  • 两个操作数必须全部合法,‘=’按钮才被激活,否则禁用(不可以点击)
  • 显示结果的控件只可查看不可修改,但支持复制到剪贴板
  • 所有子窗口的大小和位置随主窗口的缩放自动调整至最佳
    参考代码:CalculatorDialog.h CalculatorDialog.cpp main.cpp
    touch {CalculatorDialog.h,CalculatorDialog.cpp,main.cpp}
    代码1:CalculatorDialog.h
#ifndef __CALCULATORDIALOG_H
#define __CALCULATORDIALOG_H

#include <QDialog>
#include <QLabel>
#include <QPushButton>
#include <QTextCodec>
#include <QLineEdit>     //行编辑控件
#include <QDoubleValidator>  //数字验证器
#include <QHBoxLayout>    //水平布局器
#include <QFont>   //字体

//继承QDialog,当前类就也是父窗口类
class CalculatorDialog:public QDialog{
   
	Q_OBJECT  //moc  
public:
  //构造函数
  CalculatorDialog(void);
public slots: //自定义槽函数
  //设置按钮为正常或禁用状态的槽函数
  void enableButton(void);
  //点击按钮计算结果的槽函数
  void calcClicked(void);
private:
  QLineEdit* m_editX;  //左操作数
  QLineEdit* m_editY;  //右操作数
  QLineEdit* m_editZ;  //显示计算结果
  QLabel* m_label;    //加号 “+”
  QPushButton* m_button; //等号“=”
  QHBoxLayout* m_hBoxLayout; //水平布局器
  
};
#endif   //__CALCULATORDIALOG_H

代码2:CalculatorDialog.cpp

#include "CalculatorDialog.h"
//构造函数
CalculatorDialog::CalculatorDialog(void){
   
	setWindowTitle("计算器");  //窗口标题
	QFont font; //字体
	font.setPointSize(20);  //字体大小:20
	setFont(font);  //设置字体

	//左操作数,参数this表示父窗口指针
	m_editX = new QLineEdit(this);
	//设置文本对齐方式:右对齐
	m_editX->setAlignment(Qt::AlignRight);
        //设置数字验证器,只能输入数字形式的文本内容
	m_editX->setValidator(new QDoubleValidator(this));
	
	//右操作数
	m_editY = new QLineEdit(this);
	m_editY->setAlignment(Qt::AlignRight);
	m_editY->setValidator(new QDoubleValidator(this));
	
	//显示计算结果
	m_editZ = new QLineEdit(this);
	m_editZ->setAlignment(Qt::AlignRight);
	m_editZ->setReadOnly(new QDoubleValidator(this));
   
	//"+"
	m_label = new QLabel("+",this);
	//"="
	m_button = new QPushButton("=",this);
	m_button->setEnabled(false); //设置按钮禁用状态
	//布局器:自动调整大小和位置
	m_hBoxLayout = new QHBoxLayout(this);
	//将控件按水平方向添加到布局器中
	m_hBoxLayout->addWidget(m_editX);
	m_hBoxLayout->addWidget(m_label);
	m_hBoxLayout->addWidget(m_editY);
	m_hBoxLayout->addWidget(m_button);
	m_hBoxLayout->addWidget(m_editZ);
	//设置布局器
	setLayout(m_hBoxLayout);
	
	//连接信号和槽函数
	//左右操作数文本改变时,将会发送textChaned信号,连接设置按钮为正常或禁用状态的槽函数
	connect(m_editX,SIGNAL(textChanged(QString)),this,SLOT(enableButton(void)));
	connect(m_editY,SIGNAL(textChanged(QString)),this,SLOT(enableButton(void)));
        //点击等号按钮,发送clicked信号,连接计算结果的槽函数
	connect(m_button,SIGNAL(clicked(void)),this,SLOT(calcClicked(void)));
	
}

//设置按钮为正常或禁用状态的槽函数
void CalculatorDialog::enableButton(void){
   
	bool bXOk,bYOk;
	//text():获取文本内容(QString)
	//toDouble();将QString转换为字符串,如果转换失败将bXOk置false,成功置true
	m_editX->text().toDouble(&bXOk);
	m_editX->text().toDouble(&bYOk);
	//如果左右操作数都输入有效数据,设置按钮为正常状态否则设置禁用状态
	m_button->setEnabled(bXOk && bYOk);
}

//点击按钮计算结果的槽函数
void CalculatorDialog::calcClicked(void){
   
	//计算相加结果
	double res = m_editX->text().toDouble()+m_editY->text().toDouble();
	//将结果转为QString,number:将参数的数字转换为QString
	QString str = QString::number(res);
	//显示结果结果
	m_editZ->setText(str);
}

代码3:main.cpp

#include <QApplication>
#include "CalculatorDialog.h"
int main(int argc,char **argv){
   
  QApplication app(argc,argv);

  CalculatorDialog dialog;
  dialog.show();

  return app.exec();
}

编译

#1. 执行
qmake -project 

#2. 在Calculator.pro 工程文件里面追加 
  QT+=widgets
  QT+=core5compat  

#3.执行
qmake 

#4.执行
 make 

测试
./Calculator




案例2

  1. 获取系统时间
    –》使用面向对象的Qt编程方法创建获取时间的窗口
    –》点击获取时间按钮,通过自定义的槽函数获取时间并显示到标签
    提示:
```
class TimeDialog:public QDialog{
    Q_OBJECT
public:
    TimeDialog(void){界面初始化,信号和槽连接}
public:
    void getTime(void){//获取系统时间的槽函数
        Qtime time = QTime::currentTime();
         time.toString("hh:mm:ss");
         //将字符串时间显示到Label  
    }
private:
    QLabel *m_label;
    QPushButton* m_button;
}; 
```

参考代码:TimeDialog.h , TimeDialog.h ,main.cpp
touch {TimeDialog.h , TimeDialog.h ,main.cpp}
代码1:TimeDialog.h

#ifndef __TIMEDIALOG_H
#define __TIMEDIALOG_H

#include <QDialog>
#include <QLabel>
#include <QPushButton>
#include <QVBoxLayout>  //垂直布局器
#include <QFont>
#include <QTime>  //时间
class TimeDialog:public QDialog{
   
  Q_OBJECT
public:
  TimeDialog(void);  //构造汉函数
public slots:
  void getTime(void); //获取系统时间的槽函数
private:
  QLabel* m_label;       //显示时间标签
  QPushButton* m_button;  //获取时间的按钮
  QVBoxLayout* m_vBoxLayout; //垂直布局器
};

#endif  //__TIMEDIALOG_H

代码2:TimeDialog.cpp

#include "TimeDialog.h"
//构造函数
TimeDialog::TimeDialog(void){
   
  //界面初始化
  setWindowTitle("系统时间");  //设置窗口标题
  QFont font;
  font.setPointSize(20);
  setFont(font);  //设置字体大小
  m_label = new QLabel(this);  //显示系统时间标签
  //设置标签边框样式:凹陷面板
  m_label->setFrameStyle(QFrame::Panel|QFrame::Sunken);
  //设置文本方式:水平和垂直都居中
  m_label->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);

  m_button = new QPushButton("获取系统时间",this);

  //设置垂直布局器:自动调正大小和位置
  m_vBoxLayout = new QVBoxLayout(this);
  m_vBoxLayout-> addWidget(m_label);
  m_vBoxLayout->addWidget(m_button);
  setLayout(m_vBoxLayout);

  //信号和槽连接,点击获取时间按钮,发送clicked信号连接到获取时间的槽函数
  connect(m_button,SIGNAL(clicked(void)),this,SLOT(getTime(void)));
}

//获取系统时间的槽函数
void TimeDialog::getTime(void){
   
  QTime time = QTime::currentTime();   //获取系统时间
  QString str = time.toString("hh:mm:ss");  //将时间转换为QString
  m_label->setText(str);  //将字符串时间显示到label控件上
}

代码3:main.cpp

#include <QApplication>
#include "TimeDialog.h"

int main(int argc,char** argv){
   
  QApplication app(argc,argv);

  TimeDialog dialog;
  dialog.show();

  return app.exec();
}

添加:QT+=widgets
编译

qmake -project
qmake
make 


六、Qt设计师使用(designer)

什么是QT设计师?
Qt设计师(designer)是Qt工具,用于设计和构建带有Qt控件的图形用户界面GUI应用程序,它使用"所见即所得"的方式编写自定义窗口或对话框,可以方便的修改窗口
及控件的大小,位置,字体等相关属性,同时可以方便的预览界面效果
Qt设计师中用可以通过鼠标直接拖曳这些窗口控件,设置相关属性,能够高效、快速实现图形用户的设计,让界面实现更加直观形象,并可以自动生成和界面相关代码,
进而简化编程,提高代码编写效率
在这里插入图片描述

案例:使用设计师重构加法计算器

1. 创建工程目录

mkdir Calculator2

2. 进入工程目录,执行“designer”启动设计师

1)在新建窗体界面,选择模板(父窗口):“Dialog without Buttons”
在这里插入图片描述

2)在设计师界面中完成ui设计
–》从“Widget Box”里面找到需要使用控件,拖拽到父窗口上面
PushButton(1个) LineEdit(3个) Label(1个)
在这里插入图片描述
在这里插入图片描述

–》设置父窗口和每个控件的属性
父窗口(QDialog)
objectName(对象名):CalculatorDialog
注:将来会根据父窗口的对象名生成一个名字相同类,包含在设计师完成的所有代码
font(字体):点大小(20)
windowTitle(标题):加法计算器
在这里插入图片描述
在这里插入图片描述

左操作数(QLineEdit)
objectName:m_editX
alignment:水平(AlignRight)
在这里插入图片描述

右操作数(QLineEdit)
objectName:m_editY
alignment:水平(AlignRight)
在这里插入图片描述

显示结果(QLineEdit)
objectName:m_editZ
alignment:水平(AlignRight)
readOnly(只读):勾选√
在这里插入图片描述

加号标签:
objectName:m_label
text:“+”
在这里插入图片描述

等号按钮:
objectName:m_button
enabled:去掉勾选√(禁用)
text:“=”
在这里插入图片描述

–》调整父窗口和控件的大小和位置
方法1:鼠标拖拽
方法2:键盘,调整位置(方向键、ctrl+方向键) 调整大小(shitf+方向键、ctrl+shift+方向键)
方法3:设置geometry属性,调整位置(x,y) 大小(宽度,高度)
方法4:使用布局器自动调整 //推荐
在这里插入图片描述

使用布局器自动调整
在这里插入图片描述
在这里插入图片描述

–》窗体预览
–》保存(ctrl+s),指定文件名“CalculatorDialog.ui”
在这里插入图片描述

–》关闭,最终在工程目录下得到一个"CalculatorDialog.ui"文件
如果需要重新编辑:
designer CalculatorDialog.ui

3. 使用界面编辑器(uic),

将“CalculatorDialog.ui(xml)”转换为“ui_CalculatorDialog.h(c++)”

  1. 转换命令
    uic CalculatorDialog.ui -o ui_CalculatorDialog.h

  2. 转换后“ui_CalculatorDialog.h”文件内容

      class Ui_CalculatorDialog{
         
      public:
          图形控件相关对象指针声明;
          void setupUi(QDialog*){
         //界面初始化
          创建图形控件、属性设置..
          }
      };	
      namespace Ui{
         
        class CalculatorDialog:public Ui_CalculatorDialog{
         };
      }
    
 注:Ui名字空间的子类(Ui::CalculatorDialog)和上面基类(Ui_CalculatorDialog)相同

4. 使用“ui_CalculatorDialog.h”文件,复用里面代码方法

  1. 方法1:继承
    class MyClass:public Ui::CalculatorDialog{
    //将界面相关代码继承过来直接使用
    };

  2. 方法2:组合

 ```c
    class MyClass{
    public:
        MyClass():ui(new Ui::CalculatorDialog){}
    private:
    //通过“ui->”访问和界面相关代码
        Ui:: CalculatorDialog* ui;
    };
  ```

5. 编写代码、构建、测试

1)继承方式
参考代码1:CalculatorDialog.h 继承了父窗口

#ifndef __CALCULATORDIALOG_H
#define __CALCULATORDIALOG_H

#include "ui_CalculatorDialog.h"//继承方式

//自定义计算器窗口类,继承了父窗口,那么当前类就也是一个父窗口
class CalculatorDialog:public QDialog,public Ui::CalculatorDialog{
          
    Q_OBJECT
public:
    //构造函数
    CalculatorDialog(void);
public slots:
    //恢复按钮为正常状态槽函数
    void enableButton(void);
    //计算和显示结果的槽函数
    void calcClicked(void);
};
#endif//__CALCULATORDIALOG_H

参考代码2:CalculatorDialog.cpp 使用setupUi(this); 界面初始化

#include "CalculatorDialog.h"
//构造函数
CalculatorDialog::CalculatorDialog(void){
   
    //界面初始化
    setupUi(this);
    m_editX->setValidator(new QDoubleValidator(this));//设置验证器
    m_editY->setValidator(new QDoubleValidator(this));//设置验证器

    //信号和槽连接
    //左右操作数文本改变时,发送信号textChanged(QString)
    //注:如果连接的槽函数是当前父窗口中自定义的,那么第三个参数一定
    //是this.
    connect(m_editX,SIGNAL(textChanged(QString)),
            this,SLOT(enableButton(void)));
    connect(m_editY,SIGNAL(textChanged(QString)),
            this,SLOT(enableButton(void)));
    //点击等号按钮,发送信号clicked()
    connect(m_button,SIGNAL(clicked(void)),
            this,SLOT(calcClicked(void)));
}
//恢复按钮为正常状态槽函数
void CalculatorDialog::enableButton(void){
   
    bool bXOk;//记录左操作数是否输入了有效数据
    bool bYOk;//记录右操作数是否输入了有效数据
    //text():获取文本内容(QString)
    //toDouble():将QString转换为double,参数保存转换是否成功结果
    m_editX->text().toDouble(&bXOk);
    m_editY->text().toDouble(&bYOk);
    //如果左右操作数都输入了有效数据,则恢复按钮为正常可用状态,否则
    //设置为禁用状态.
    m_button->setEnabled(bXOk && bYOk);
}
//计算和显示结果的槽函数
void CalculatorDialog::calcClicked(void){
   
    //计算相加结果
    double res = m_editX->text().toDouble() + 
                 m_editY->text().toDouble();
    //将数字结果转换为字符串
    //number():将double转换为QString
    QString str = QString::number(res);
    //显示结果
    //setText():设置控件要显示的文本
    m_editZ->setText(str);
}

参考代码3:main.cpp

#include <QApplication>
#include "CalculatorDialog.h"

int main(int argc,char** argv){
   
    QApplication app(argc,argv);
    
    CalculatorDialog dialog;
    dialog.show();

    return app.exec();
}

构建、测试

qmake -project
#添加QT+=widgets
qmake 
make

2)组合方式

参考代码1:CalculatorDialog.h 继承了父窗口

#ifndef __CALCULATORDIALOG_H
#define __CALCULATORDIALOG_H

#include "ui_CalculatorDialog.h"//组合方式

//自定义计算器窗口类,继承了父窗口,那么当前类就也是一个父窗口
class CalculatorDialog:public QDialog{
   
    Q_OBJECT
public:
    //构造函数
    CalculatorDialog(void);
    //析构函数
    ~CalculatorDialog(void);
public slots:
    //恢复按钮为正常状态槽函数
    void enableButton(void);
    //计算和显示结果的槽函数
    void calcClicked(void);
private:
    //将来通过"ui->"访问和界面相关代码
    Ui::CalculatorDialog* ui;
};
#endif//__CALCULATORDIALOG_H

参考代码2:CalculatorDialog.cpp

#include "CalculatorDialog.h"
//构造函数
CalculatorDialog::CalculatorDialog(void)
    :ui(new Ui::CalculatorDialog){
   
    //ui = new Ui::CalculatorDialog;
    //界面初始化
    ui->setupUi(this);
    ui->m_editX->setValidator(new QDoubleValidator(this));//设置验证器
    ui->m_editY
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值