QT基础——核心模块QtCore
qt core 提供了元对象系统,扩展了c++ 在元对象系统的基础上,qt又提供了信号/槽、property以及对象树等特性
- The Meta-Object System
- The Property System
- Object Model
- Object Trees & Ownership
- Signals & Slots
Meta-Object系统
较复杂,暂时跳过
Property 系统
例子:
class MyClass : public QObject
{
Q_OBJECT
Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
public:
MyClass(QObject *parent = nullptr);
~MyClass();
enum Priority { High, Low, VeryHigh, VeryLow };
Q_ENUM(Priority)
void setPriority(Priority priority)
{
m_priority = priority;
emit priorityChanged(priority);
}
Priority priority() const
{ return m_priority; }
signals:
void priorityChanged(Priority);
private:
Priority m_priority;
};
信号 & 槽
一个普通的c++类:
class Counter
{
public:
Counter() { m_value = 0; }
int value() const { return m_value; }
void setValue(int value);
private:
int m_value;
};
添加信号槽:
#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;
};
信号 & 槽的连接用connect函数:
connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(Qbject*)));
connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed()));
connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed()));
下面的例子绑定了QProcess的finished信号和afterBuild函数,
//编译keil工程
void ExeCmd::buildProj(QString uv4, QString home){
qDebug() << "Enter build buildProj()";
if(uv4 == nullptr || home== nullptr){
qDebug() << "param invalid";
return;
}
if(!QFile::exists(uv4)){
qDebug() << "uv4 not exit";
return;
}
QProcess *myProcess = new QProcess();
connect(myProcess, &QProcess::finished, this, &ExeCmd::afterBuild);
QStringList arguments;
arguments << "-r" << home+ "/App.uvproj" << "-t" << "App";
myProcess->start(uv4, arguments);
}
//编译完成之后拷贝二进制文件到缓存目录
void ExeCmd::afterBuild(int val){
qDebug()<< "Enter afterBuild()" << val;
QProcess* obj = (QProcess*)sender();
qDebug()<<"result:" << QString::fromUtf8(obj->readAll());
delete obj;
//copy hex file to temp
CfgFile cf = CfgFile();
copyHexToTempFolder(cf.getTargetPath());
}
资源系统
https://doc.qt.io/qt-6/resources.html
Qt资源系统是一种独立于平台的机制,用于在应用程序中传送资源文件。如果您的应用程序始终需要一组特定的文件(如图标、翻译文件、图像),并且您不想使用特定于系统的方法打包和查找这些资源,请使用它。
最常见的是,资源文件嵌入到应用程序可执行文件中,或者嵌入到应用程序可执行文件加载的库和插件中。或者,资源文件也可以存储在外部资源文件中。
资源编译器rcc
资源系统基于Qt的rcc资源编译器,构建系统和Qt运行时API之间的密切合作。
rcc读取资源文件(图标、翻译文件、图像)并翻译成 C++ 或 Python 源文件,或者翻译成文件 *.rcc
默认情况下,rcc将生成C++源代码,然后将其编译为可执行文件或库的一部分。
-g
选项可以指定生成类型,-g, --generator <cpp|python|python2> Select generator
Qt资源集合文件 .qrc
是一个xml文件,例子:
<RCC>
<qresource prefix="/">
<file>images/copy.png</file>
<file>images/cut.png</file>
<file>images/new.png</file>
<file>images/open.png</file>
<file>images/paste.png</file>
<file>images/save.png</file>
</qresource>
</RCC>
cmake使用rcc的第一种方式
在cmake中使用qrc文件非常方便,启用CMAKE_AUTORCC
然后直接把qrc文件当成代码源文件即可:
set(CMAKE_AUTORCC ON)
qt_add_executable(my_app
application.qrc
main.cpp
)
CMAKE_AUTORCC
是cmake提供的支持,而不是qt自定义的类型,参考 https://cmake.org/cmake/help/latest/prop_tgt/AUTORCC.html
cmake使用rcc的第二种方式
除了使用CMAKE_AUTORCC
的方式,还可以使用qt提供的函数qt_add_resources
:
qt_add_resources(my_app "app_images"
PREFIX "/"
FILES
images/copy.png
images/cut.png
images/new.png
images/open.png
images/paste.png
images/save.png
)
使用这种方法的好处是不用编写qrc文件
引用添加到qrc的文件
在使用qrc的方式中,如果资源文件已经被添加到qrc文件,那么在代码中是不需要使用真实路径来引用文件的,有两种方式引用文件(Path 和 URL,都是资源系统内部相对的):
举个例子,在qml中Image对象显示一张照片,需要赋值source属性,而Image.source是url类型:
那么代码中就这样写:
Image {
Layout.preferredHeight: 100
Layout.preferredWidth: 100
//也可以简写成 source: "/imgs/rebuild.png"
source: "qrc:/imgs/rebuild.png"
}
c++代码中函数参数是url类型的同样也可以:
QQmlApplicationEngine engine;
engine.load(QUrl("qrc:/myapp/main.qml"));
以上都是使用url,path的方式也举个例子:
cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this);
QIcon接收参数是QString fileName,这里直接赋值的是资源系统提供的path而不是真实的文件path。
使用path的例子还有QTranslator,如果我们有两份翻译文件en_US.qm
和zh_CN.qm
把他们添加到qrc之后就可以:
void QmlLanguage::setLanguage(int indexOfLanguage)
{
QTranslator translator;
if (indexOfLanguage == 0)
{
translator.load(":/en_US.qm");
}else if (indexOfLanguage == 1) {
translator.load(":/zh_CN.qm");
}else{
translator.load(":/en_US.qm");
}
//QGuiApplication &app
app->installTranslator(&translator);
//QQmlApplicationEngine& engine
engine->retranslate();
}
qrc支持的类型
上文中已经出现过的有图片和翻译文件(.qm),除此之外还支持qml文件,比如我们自定义的控件
自定义控件的使用方式:
(1)编写qml文件
(2)添加到cmake
qt_add_qml_module(PerfTestTool
URI App
VERSION 1.0
QML_FILES main.qml ./controls/XBtn.qml ./controls/XTextField.qml
)
(3)import 路径 :import "./controls"
,这是用真实路径的方式
qml文件添加到qrc之后,还可以用url的方式:import "qrc:/controls"
。
QtCore提供的c++类
https://doc.qt.io/qt-6/qtcore-module.html
国际化
首先通过工具lupdate
把qml文件抽出来包含qsTr()
的文本
lupdate main.qml -ts zh_CN.ts en_us.ts
ts文件其实是xml,定位qsTr在qml文件的位置
然后使用工具Linguist
打开ts文件,翻译成目标语言
翻译完成后,发布,就可以得到qm文件
qm文件不是文本文件
再然后把qm文件进资源系统,就可以用c++切换语言了
void QmlLanguage::setLocalLanguage(){
QTranslator translator;
QLocale locale;
if( locale.language() == QLocale::English ) {
translator.load(":/en_us.qm");
}
else if( locale.language() == QLocale::Chinese ) {
translator.load(":/zh_CN.qm");
}
m_app->installTranslator(&translator);
//重新载入语言包
m_engine->retranslate();
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现