文章目录
序言
本文章记录本人历经5年Qt 开发过程中的技术见解,所有内容都经过实战验证。
如果阅读者发现一些错误,欢迎反馈,评论,留言。
部分内容参杂c++ c unix 等基础知识,如果遇到不懂的,先搞懂这些基础之后再回头学习。
如何使用qtcreator 新建一个app 工程等基础操作,请自行参照qt官方开发手册。
目前整理编写到 “Qt数据模型之前”
相信本内容会对任何从事qt相关开发的人有所帮助。
开发环境依赖
qt 对跨平台支持良好,因此,使用windows10 与ubuntu20以及任意android手机 进行代码验证
qt5.15.2 online 安装
qt online 下载链接:link
windows依赖
对于windows 开发,需要window10 以上, 最好安装vs2022 ,此版本可以下载msvc2019 编译器兼容qt 5.15.2的msvc2019 版本套件
virtual studio
virtual studio下载:link
ubuntu依赖(桌面linux)
笔者使用ubuntu20, 更低的ubuntu版本对qt5.15.2支持不友好
ubuntu iso 下载:link
qt for android
对于android 开发,需要安装android studio
优点如下:
可以利用该ide 管理sdk manager
可以开发原生android apk 与 qt for android 做对比
android studio
android studio下载:link
虚拟机vmware workstation
为了使用PC双系统,使用在windows PC 安装虚拟机的方法安装
下载链接:link
qtcreator 环境配置
不同的系统依赖不同的构建套件来编译qt app,如下图:
windows + vs2022 + qt
正确安装vs2022 后启动qtcreator后会自动检测出套件
ubuntu + qt
apt 安装 g++ ,启动qtcreator后会自动检测出套件
android + qt
正确安装android studio 后启动qtcreator后进行套件配置:
注意
1. qt5.15.2 必须使用jdk11, jdk8的话 sdk manager 运行有问题 无法配置成功。
*2. 在配置好android sdk 路径之后保存配置,重新打开设置会弹出更新需求,一路安装全部就好,主要是自动安装了以下套件
NDK (Side by side) 23.1.7779620
Android SDK Platform 31
Android SDK Command-line Tools (latest)
NDK (Side by side) 21.3.6528147
Android SDK Build-Tools 31
Google USB Driver
QT输入输出
由于qt大部分内容是基于c++的,输入输出兼容c和c++ 的标准库:如 printf() getchar() std:cout std:cin
同时qt又封装了qt特色的日志系统,qlogging
QT输出
输出例程 qDebug
。
#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
int a = 5;
qDebug()<<a;
return 0;
}
qDebug 宏定义
该函数构造一个QMessageLogger 实例。并使用其内部的debug
QT_MESSAGELOG_FILE 宏定义
该宏使用C语言的__FILE__ 获取当前源文件名
QT_MESSAGELOG_LINE 宏定义
该宏使用C语言的__LINE__ 获取当前源文件行
QT_MESSAGELOG_FUNC 宏定义
该宏使用了Q_FUNC_INFO,
Q_FUNC_INFO 宏定义
该宏是函数方法签名,不同的编译器版本实现不同,
以下是mingw 版本(gnuc 版本) 和msvc 版本的实现
QMessageLogger 内部函数
消息日志类实现了5个函数 debug noDebug info warning critical
Q_ATTRIBUTE_FORMAT_PRINTF 宏
Q_ATTRIBUTE_FORMAT_PRINTF 是对printf的attribute格式化
gnuc 可以使用__attribute__(format(printf, a, b))格式化函数,以提供函数参数检测
QMessageLogger .debug
该函数使用qt_message 函数返回构建的QString,同时如果是致命错误就调用致命错误处理函数
qt_message
该函数使用QString::vasprintf构建QString 并使用qt_message_print输出到输出设备
qt_message_print
使用fprintf 输出到stderr, 或者使用自定义注册的消息输出函数
在此可知QMessageLogger默认使用 stderr作为输出设备
后续会说明自定义日志消息输出函数的用法
注册输出日志自定义函数
qInstallMessageHandler 宏定义
用于注册消息处理函数
下面展示用法,内容为 main.cpp
。
在本例程中,注册了qt输出函数接口messageOutput.
所以除了qCritical() 保持输出设备为stderr外, 其余log函数的输出设备修改为stdout。
#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <stdio.h>
#include <QLoggingCategory>
void messageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QByteArray msgAry = msg.toUtf8();
switch (type) {
case QtCriticalMsg:
fprintf(stderr, "%s\n", msgAry.constData());
fflush(stderr);
break;
default:
fprintf(stdout, "%s\n", msgAry.constData());
fflush(stdout);
break;
}
}
int main(int argc, char *argv[])
{
qInstallMessageHandler(messageOutput);
int a = 5;
qDebug()<<a;
qCritical()<<a;
}
QT输入与qt 事件系统
qt 的输入可以使用c\c++ 的自定义处理,比如使用 while 循环读取标准输入
也可以使用QAapplication 进入事件循环,鼠标键盘等设备输入解析输入后会生成QEvent子类, 分发到各个事件处理实例中。
QWidget部分事件函数
其中event 是事件处理总函数,所有进入QWidget 的事件将经过event 分发到对应的处理函数例如 mousePressEvent, keyPressEvent,重载事件函数可以自定义QWidget 的行为。
eventtestwidget例程重载了QWidget鼠标单击事件,输出事件类型和单击坐标后,进入父类(QWidget)的事件处理函数:
eventtestwidget.h
#ifndef EVENTTESTWIDGET_H
#define EVENTTESTWIDGET_H
#include <QWidget>
class EventTestWidget : public QWidget
{
Q_OBJECT
public:
explicit EventTestWidget(QWidget *parent = nullptr);
signals:
protected:
void mousePressEvent(QMouseEvent* event);
};
#endif // EVENTTESTWIDGET_H
eventtestwidget.cpp
#include "eventtestwidget.h"
#include <QDebug>
#include <QMouseEvent>
EventTestWidget::EventTestWidget(QWidget *parent)
: QWidget{
parent}
{
}
void EventTestWidget::mousePressEvent(QMouseEvent* event)
{
qDebug()<<event->type()<<event->pos();
QWidget::mousePressEvent(event);
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include "eventtestwidget.h"
void