嵌入式应用程序设计(Qt)
1.信号与槽
1-1:connect
connect有3种连接方式,分别是:直接连接和队列连接、自动连接
直接连接:信号槽在信号发出者所在的线程中执行
队列连接:信号在信号发出者所在的线程中执行,槽函数在信号接收者所在的线程中执行
自动连接:多线程时为队列连接函数,单线程时为直接连接函数
连接函数原型:
QObject::connect(&发送对象,SIGNAL(信号名(形参类型列表)),&接收对象,SLOT(槽名(形参类型列表)));
关联规则:
1.一个信号可以关联到多个槽上
2.多个信号也可以关联到同一个槽上
3.一个信号也可以关联到另一个信号上
4.信号与槽之间传送消息通过参数列表实现,参数类型一致且一一对应
5.信号参数的个数多于槽参数的个数时,多余的会被忽略掉
信号参数个数小于槽参数个数时,可:
1.通过QSignalMapper类实现信号映射
QSignalMapper mapper; QObject::connect(&btn2, SIGNAL(clicked()), &mapper, SLOT(map())); mapper.setMapping(&btn2, "我是一行文字"); QObject::connect(&mapper, SIGNAL(mapped(const QString&)), &lineEdit, SLOT(setText(const QString&)));
2.通过Lamda表达式实现参数传递
QObject::connect(&btn2,&QPushButton::clicked, &lineEdit,[&]{lineEdit.setText("我是一行文字");});
★★★1-2: 列举出信号和插槽有以下几种用法:
1.一个信号可以连接多个槽:
connect(slider,SIGNAL(valueChanged(int)),spinBox,SLOT(setValue(int)))
connect(slider,SIGNAL(valueChanged(int)), this,SLOT(updataStatusBarIndictor(int)));
2.多个信号连接同一个槽:
connect(lcd,SIGNAL(overflow(int)),this,SLOT(handleMathError(int)))
connect(calculator,SIGNAL(divisionByZero(int)), this,SLOT(handleMathError(int)));
3.一个信号可以与另外一个信号相连接:
connect(lineEdit,SIGNAL(textchanged(constQString&)),this,SLOT(updateRecord(constQString&)))
4.连接可以被移除:
disconnect(lcd,SIGNAL(overflow(int))this,SLOT(handlMathError(int)))
参考:
Qt-窗口显示-信号和槽连接QSpinbox&QSlider_@WitnesS的博客-CSDN博客_qspinbox信号槽
2.Qt中的常用标准对话框
Qt中的常用标准对话框有FileDialog、ColorDialog、FontDialog
对话框 | 常用静态函数名称 | 函数功能 |
QFileDialog (文件对话框) |
QString getOpenFileName() QStringList getOpenFileNames() QString getSaveFileName() QString getExistingDirectory() Qurl getOpenFile() |
选择打开一个文件 选择打开多个文件 选择保存一个文件 选择一个已有的目录 选择打开一个文件,可选择远程网络文件 |
QColorDialog (颜色对话框) |
QColor getColor() | 选择颜色 |
QFrontDialog (字体对话框) |
QFont getFont() | 选择字体 |
此外,标准对话框还有:QinputDialog(输入对话框)、QMessageBox(消息框)
Qt标准输入对话框提供了4种数据类型的输入,它们是:int类型的数据、字符串,double类型,下拉列表框的条目
单行字符串输入对话框(getText函数)
整数输入对话框(getInt函数)
浮点数输入对话框(getDouble函数)
下拉列表选择输入对话框(getItem函数)
详情在这里: Qt:30---QInputDialog标准输入对话框_董哥的黑板报的博客-CSDN博客_qinputdialog
3.Qt中常用的布局管理器
Qt中常用的布局管理器有QHBoxLayout、QVBoxLayout和QGridLayout等
QHBoxLayout:水平布局
QVBoxLayout:垂直布局
QVGridLayout:网格布局
用法详见:Qt入门 --- QGridLayout、QHBoxLayout、QVBoxLayout三种常用的布局方式_Aulistin的博客-CSDN博客_qgridboxlayout
4.Qt的GraphicsView框架结构
Qt的GraphicsView框架结构主要包含了三个主要的类,分别是: QGraphicsScene、QGraphicsView、QGraphicsItem
QGraphicsScene:场景;QGraphicsView:视图;QGraphicsItem:图元
详见:QT开发(三十九)——GraphicsView框架_生命不息,奋斗不止的技术博客_51CTO博客
5.QTimer对象
使QTimer对象开始计时的方法是start()
详情:QTimer 定时器_求道玉的博客-CSDN博客_qtimer start
Qt定时器的使用:
1.直接通过事件模式去实现
2.通过QT中的Time类来实现
定时器精度依赖于系统及硬件设计
使用定时器,可以用QObject类的定时器
6.QLabel对象
设置QLabel对象显示文本内容的方法是show()
详情: Qt学习笔记(二十七):QLabel 的常用方法_秋忆夏伤的博客-CSDN博客_qlabel构造函数
7.MVC模式
MVC 模式中的M代表Model,V代表View,C代表Controller
MVC:Model(模型)-View(视图)-Controller(控制器),是一种设计模式
8.Qt事件处理方法
QT事件:是Qt事件类的一个对象,用于描述程序内部或外部发生的事情
Qt事件的来源:将系统产生的消息转换为QT事件/Qt应用程序自身产生的
QT事件处理机制:
异步处理:Qt应用程序中维护了一个事件队列。调用QApplication::exec()时,进入事件循环:
该循环不断取出Qt事件队列并派发处理,直至为空;
再处理消息队列中的消息,转换为Qt事件,放入事件队列,直至为空;
再处理事件队列中新加入的事件,直至为空
QT事件处理方法:重载QApplication : : notify ( ) --> QObject : : event ( ) --> Qt基类事件处理函数
QApplication::notify()函数:所有事件最终都通过该函数派发给(处理该事件的)对象。
对象的event()函数:是该对象接收所有事件的入口
事件处理函数:对应着不同的事件类型。是当事件发生后,最终要调用的函数
Qt事件异步处理示意图
同步处理:事件直接被派发和处理
事件机制和信号槽机制的区别:
都是用于交互的机制
区别:
不同层面的东西发出者不同,作用也不同
信号发射并无目的;而事件有明确的接收对象
详见:QT开发(十二)——QT事件处理机制_生命不息,奋斗不止的技术博客_51CTO博客
9.窗口部件
窗口部件的父类包括QWidget、Qframe、 QScrollView
10.槽
信号和槽都在类中以成员函数的形式进行声明,槽是普通成员函数
槽的特点:
在“[访问权限] slots”后开始槽的声明;
需要实现,可有形参、可根据需要设置返回类型‘
槽本质上就是类的成员函数,可被当作普通的成员函数来使用
槽可以是虚函数,可以是公有的,保护的,也可是私有的
11.Qt支持的图像格式
Qt支持的图像格式是:PNG 、BMP 、XPM
详情:Qt可显示基本的图像类型,利用QImage、QPxmap类可以实现图像的显示,并且利用类中的方法可以实现图像的基本操作(缩放、旋转)。_ailinty的博客-CSDN博客
Qt支持GIF格式图像,但无法实现存储
12.Q_OBJECT
Q_OBJECT是宏定义,如果类里面用到了signal,必须要声明这个宏
详情:Qt之Q_OBJECT_czhzasui的博客-CSDN博客
QObject对象树是一个静态的QObjectList类对象object_trees
详情:第43篇 进阶(三)对象树与拥有权 · Qt 快速入门系列教程 (jb51.net)
Qt 中的对象树(Object Tree) - 知乎 (zhihu.com)
13.FindDialog
FindDialog(QWidget*parent=0);父参数为NULL,说明没有父控件
关于QWidget*patent=0:关于QWidget *parent=0的理解_闫有尽意无琼的博客-CSDN博客
14.对话框
对话框分为模式对话框和非模式对话框2种。
模式对话框指在用户想要对对话框以外的应用程序进行操作时,必须首先对该对话框进行响应。如单击【确定】或【取消】按钮等将该对话框关闭。
非模式对话框:当用户打开非模态对话框时,依然可以操作其他窗口。
详情:模式(态)对话框:模态对话框_百度百科 (baidu.com)
非模式(态)对话框:非模态对话框_百度百科 (baidu.com)
show()显示的对话框是无模式对话框。用exec()显示的对话框是模式对话框。
15.dropEvent()
当用户在窗口部件上放下一个对象时,就会调用dropEvent()。
详情:qt 拖放dropEvent_weixin_30362801的博客-CSDN博客
dragEnterEvent:拖动
16.UNICODE标准
内部对字符集的处理采用UNICODE标准
统一码(Unicode),也叫万国码、单一码,是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。
17.QT增加的特性
QT增加的特性包括:有效的对象通信signal和slot、可查询和可设计的对象、事件及事件过滤器。
详情:Qt对C++添加的新特性 - 酸塔 - 博客园 (cnblogs.com)
18.Qt可在多个平台的应用程序中完全应用模板
19.类的构造函数
类的构造函数被自动调用执行的情况是在定义该类的对象时
详情:C++ 类构造函数 & 析构函数 | 菜鸟教程 (runoob.com)
20.new运算符
new运算符做的三件事:获得一块内存空间、调用构造函数、返回正确的指针
详情:New运算符详解_小奔Linda的博客-CSDN博客_new运算符
new运算符的描述一般有:使用运算符new创建对象时,会调用类的构造函数;运算符new可以用来动态创建对象和对象数组;使用new运算符创建的对象可以使用运算符delete删除
21.实现Qt多线程
实现Qt多线程方式有:
1.继承QThread,实现多线程
2.继承QObject,使用moveToThread函数实现多线程
3.使用QThreadPool,搭配QRunnable
详情:Qt的4种多线程实现方式_残醉的博客-CSDN博客_qt多线程并发的处理方式
Qt中提供了QThread线程类
QThread的使用方法:Qt 线程中QThread的使用_伐尘的博客-CSDN博客_qt中qthread
22.QStyle类
详情:QStyle类参考_chenlong12580的博客-CSDN博客
★★★23.Qt Designer设计一个对话框主要步骤:
1.创建窗体并在窗体中放置各种控件
2.对窗体进行布局管理
3.设置各空间的标签顺序
4.创建信号和槽
5.连接信号和槽
★★★24.Qt中窗口对象的父子关系如何指定及指定父对象有什么作用及好处:
一般通过构造函数中的“QWidget*parent”参数指定
重要作用:
父对象show的时候会递归调用其所有子对象,让它们都显示出来
父对象被销毁时会递归销毁其所有的子对象,让内存管理更加简单
详情:QT窗口组件的父子关系 - lh03061238 - 博客园 (cnblogs.com)
★★★25.QT中的文件流(QTextStream)和数据流(QDataStream)的区别
文件流,数据流都可以操作磁盘文件,也可以操作内存数据。通过流对象可以将对象打包到内存,进行数据的传输。
文件流(QTextStream)。操作轻量级数据(int,double,QString)数据写入文本文件中以后以文本的方式呈现。
数据流(QDataStream)。通过数据流可以操作各种数据类型,包括对象,存储到文件中数据为二进制。
详情:Qt中使用流读写文件_徐kun按门铃的博客-CSDN博客_qt 流写入文件
★★★26.Qt程序设计
26-1:实现下图:
功能:点击Quit可以直接退出。
#include<QtGui/QWidget>
#include<QPushButton>
#include<QtGui>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget *pWidget=new QWidget;
QPushButton *button=new QPushButton("Quit", pWidget);
QObject::connect(button, SIGNAL(clicked()),pWidget, SLOT(close()));
pWidget->show();
return app.exec();
}
26-2:编写main 文件,实现下图。假设ui的名字为 gotocelldialog.Ui。
#include <QApplication>
#include <QDialog>
#include "ui_gotocelldialog.h"
int main(int argc, char *argv[] )
{
QApplication app(argc, argv);
Ui::GotoCellDialog ui;
QDialog *dialog = new QDialog;
ui.setupUi(dialog) ;
dialog->show() ;
return app.exec() ;
}
26-3:实现下图功能:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QFileDialog>
#include <QDebug>
#include <QPushButton>
#include <QTextStream>
#include <QFileInfo>
#include <QDateTime>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//使用connec函数,熟悉匿名表达式
connect(ui->pushButton,&QPushButton::clicked,[=](){
//点击按钮,弹出文件选择对话框
//使用对话框,获取打开路径,注意参数一是父类对象 ,参数二是对话窗口名称 参数三是默认打开路径
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open File"), "C:\\data");
//使路径显示到路径 line edit地方
ui->label->setText(fileName);
//调试的跟踪打印
qDebug()<<"文件路径为:"+fileName;
//使用Qfile操作文件
QFile file(fileName);
//打开文件,注意参数的使用,文件修饰符,文件指针,可以和之前的嵌入式环境编程的知识联系起来,包括 模式操作
file.open(QIODevice::ReadOnly);
//使用数组数据结构接读取数据
QByteArray array;
while( !file.atEnd())
{
array += file.readLine(); //按行读
}
ui->textEdit->setText(array);
//关闭文件数据流
file.close();
//编码格式类
//QTextCodec * codec = QTextCodec::codecForName("gbk");
QFileInfo info(fileName);
qDebug() << "大小:" << info.size() << " 后缀名:" << info.suffix() << " 文件名称:"<<info.fileName() << " 文件路径:"<< info.filePath();
qDebug() << "创建日期:" << info.created().toString("yyyy/MM/dd hh:mm:ss");
qDebug() << "最后修改日期:"<<info.lastModified().toString("yyyy-MM-dd hh:mm:ss");
//获取文件名,之后,根据这个文件名找到指定文件,并打开
});
}
MainWindow::~MainWindow()
{
delete ui;
}
main函数:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
26-4: 编写一个字符串处理的类,MyString,实现拷贝构造,‘=’号重载等基本函数:
#include <iostream>
class MyString
{
char *str;
public:
MyString(char *s)
{
str=new char [strlen(s)+1];
strcpy(this->str,s);
}
MyString(const MyString &temp)
{
str=new char[strlen(temp.str)+1];
strcpy(str,temp.str);
}
~MyString()
{
delete str;
}
MyString & operator = (const MyString &temp)
{
delete[] this->str;
this->str=new char[strlen(temp.str)+1];
if(this->str)
{
strcpy(this->str,temp.str);
}
return *this;
}
};
26-5:实现下图功能
功能:点击数字选择框中的上下键,数字会增减,进度条也会随之拖动;反之,拖动进度条,数字也会发生变化
#include<QApplication>
#include<QHBoxLayout>
#include<QSpinBox> //整数的显示与输入
#include<QSlider>
#include<QtGui>
int main(int argc, char* argv[])
{
QApplication app(argc, argv) ; //创建 app 的构造函数
QWidget *pWidget= new QWidget; //new 一个 Widget
pWidget->setWindowTitle("enter your age") ; //设置 caption
QSpinBox* spinbox = new QSpinBox; //new 一个 spinbox
QSlider* slider = new QSlider(Qt::Horizontal) ; //new 一个 slider
spinbox->setRange(0, 130) ; //设置范围, ->符号
slider->setRange(0, 130) ;
QObject::connect(spinbox, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int)));
QObject::connect(slider, SIGNAL(valueChanged(int)), spinbox, SLOT(setValue(int)));
//信号和槽, (发送者, 信号, 接收者, 槽) . 第一个是 spinbox 发送给 slider 的
//第二个是 slider 发送给 spinbox 的
spinbox->setValue(23) ;
//QHBoxLayout 是布局管理器, 即在水平方向上排列窗口部件
QHBoxLayout* layout = new QHBoxLayout;
layout->addWidget(spinbox) ;
layout->addWidget(slider) ;
pWidget->setLayout(layout) ;
pWidget->show() ; //窗体显示
return app. exec() ;
}