开启QT学习之路-第二天
1。先了解下QT的核心机制。
看到文江博客-零基础学 qt4 编程,有相关的文章介绍比较系统。直接先看他的13章了解下核心机制,再来编写第一个程序。
核心一-信号和槽。
还是看看官方的帮助手册怎么解释,搜索"Signals & Slots",信号与槽是对象直接的通讯机制,在“Introduction”中说,我们经常会存在很多对象之间的通讯,这个通讯可能是对象内部,也可能是不同的对象之间的,但是其他工具组件我猜他说的是C++需要指向函数的指针来进行回调,这个机制虽好,但是有回调不直观,而且函数回调类型正确性有风险,信号和槽是可以完全独立,两个没有连接前谁也不知道谁,可以一对多,也可以多对一,也可以多对多,看看两个是完全独立的,还是看图直观。
学习下他的信号和槽例程:
#include <QObject>
class Counter : public QObject
{
Q_OBJECT
public:
Counter() {
m_value = 0; }
int value() const {
return m_value; }
public slots://槽
void setValue(int value);//可以当成普通函数同时也可作为槽声明
signals://信号
void valueChanged(int newValue);
private:
int m_value;
};
void Counter::setValue(int value)//槽执行功能
{
if (value != m_value) {
m_value = value;
emit valueChanged(value);
}
}
Counter a, b;
QObject::connect(
&a,
&Counter::valueChanged,
&b,
&Counter::setValue);
a.setValue(12); // a.value() == 12, b.value() == 12
b.setValue(48); // a.value() == 12, b.value() == 48
//a的信号是valueChanged,槽是b的setValue
//setValue的函数体又执行了赋值和触发信号
//过程是a.setValue(12):a的m_value=12,b的m_value=12,感觉像是又触发了b.setValue,但是没有连接b的valueChanged所以不执行。
//执行b.setValue(48);a的m_value=12保持不变,b的setValue执行了一次,但是没有连接槽同样不执行触发所以b的m_value=48;
如果是C++怎么做
声明
class Counter
{
public:
Counter() {
m_value = 0; }
int value() const {
return m_value; }
void setValue(int value);
private:
int m_value;
};
Counter a,b;
a.setValue(12); b.setValue(12);
b.setValue(48);
//就程序来说好像C++更简单呀???这个后面再去体会吧
注意几种连接方式:
connect(sender, &QObject::destroyed, this, &MyObject::objectDestroyed);
connect(sender, &QObject::destroyed, this, [=](){
this->m_objects.remove(sender); });
connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(Qbject*)));
connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed()));
connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed()));
connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed(QObject*)));//这是错误的
connect(action, &QAction::triggered, engine,[=]() {
engine->processAction(action->text()); });
核心二-元对象系统(The Meta-Object System)
还是帮助手册
Qt’s meta-object system provides the signals and slots mechanism for inter-object communication, run-time type information, and the dynamic property system.
1.提供了支持对象间通信的信号与槽机制、实时类型信息和动态属性系统等方面的功能。
2.元对象系统基于三件东西,
QObject类是他的基类,
Q_OBJECT 宏,
the Meta-Object Compiler (moc) 元对象编译器。
这东西应该是他内部自己自动处理的,不大懂。
核心三-事件模型QEvent
创建、交付、循环模型、自定义事件, Qt 的事件处理机制主要是基于 QEvent 类来实现 的,QEvent 类是其他事件类的基类,编程人员可以对应用程序级别和对象级别中的事件进行监控和过滤。
编写第一个程序
不得不说官方的帮助手册相当好使。基本全部包含了编程所需要的。看下他指导的步骤:IDE使用,管理工程文件,设计用户接口,编写代码,编译和运行,测试,高级使用,获取帮助。
IDE-QTCreator来看看
欢迎界面-有很多的模板这个目前我还用不到,编辑-写代码,设计-UI设计器,debug(????),项目-配置文件,帮助文件必须知道,再下面发布,运行,调试,编译。
建工程
这三个帮助文档有说明可以搜索下,官网也有说明这三个编译系统,意思就是19年时候Qbs发布最后一版本,后面就不准备用了,qmake使用的人最多,但是现在cmake也很多,而且重点精力在开发CMAKE.而且最新QT6也是重点CMAKE。我的版本比较低还是先用qmake吧。
看帮助文档,QMainWindow为用户界面构建应用程序提供了一个主窗口,QWidget用在所有的窗体上,QDialog对话框窗口是顶级窗口,主要用于短期任务和与用户的简短通信。QMainWindow和QDialog都是QWidget的子窗口。我不需要太复杂,就先用QMainWindow.
我装了VS2017所以有第一个,还是用mingw吧。
创建完毕,看下项目功能内容。工程myQT01.pro,头文件mainwindow.h,c文件main.cpp,mainwindow.cpp,窗体mainwindow.ui,左侧现在该亮的都亮了,
这里的编译路径还是要重新设置下比较好。
这里的在编辑位置有个Debug还不知道干吗的????
再来看看代码部分,程序入口都是main函数,他调用了头函数"mainwindow.h",而他调用了类库QMainWindow,查查看帮助文档。
这玩意又是从Widget来的,再看看,
QObject(QT += core)和QPaintDevice(QT += gui)他已经没有继承类了,再深入又要到底层了,先了解下这两个类,
QObject目录指示内容:他的属性,公用的功能函数,槽函数,信号,静态公用成员变量,受保护的功能函数,关联的非成员变量(这个也不知道是不是这个意思),宏(这个看了下内容不是很明白,这个类感觉上所有的核心机制都在这个类中体现了,也是和常用的C++不同的地方)先不去深入吧。
QPaintDevice看描述就是画图用,有窗体所以有画图也很正常。
QWidget内容蛮多的。
QMinWindow同样先有个概念再说。
再来看看代码吧:
基础知识c++中:
1。“.”访问类或者结构体的成员,“->”指针的成员
2。“::”在没有实例化时访问成员变量。“:”表示继承
举例:
C为类,类里面的成员有a,b;
C *m 想要提取成员*m.a或者m->a(这个访问m必须是指针);
C m 提取成员m.a
举例:
MainWindow::MainWindow(QWidget *parent)第一个是类,第二个是他的成员
//头文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow; }//Qt.core有说明
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;//命名空间(Ui)的成员::MainWindow
};
#endif // MAINWINDOW_H
//cpp文件
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow)//ui这个命名空间不知道什么情况,不看了先????
{
ui->setupUi(this);//void QWidget::setupUi(QWidget *widget)有这个定义,ui->setupUi是几个意思???Ui什么时候变成指针了?????
}
MainWindow::~MainWindow()//析构函数
{
delete ui;
}
#include "mainwindow.h"//双引号一般自定义的
//他是不依赖QWidget应用却服务去他的库文件,
//主要用来创建和结束窗体应用程序
#include <QApplication>//尖括号一般是系统头文件,
int main(int argc, char *argv[])
{
QApplication a(argc, argv);//窗体应用的初始化
MainWindow w;//创建一个窗体类,进入类文件看下
w.show();//显示这个窗体
return a.exec();//窗体应用的结束
}
虽然程序不太理解CTRL+R运行一下:
虽然好几个地方还不理解,但是至少先把窗体运行出来了。