Q_PROPERTY宏定义一个返回类型为type,名称为name的属性.
Q_PROPERTY(type name
READ getFunction
[WRITE setFunction]
[RESET resetFunction]
[NOTIFY notifySignal]
[DESIGNABLE bool]
[SCRIPTABLE bool]
[STORED bool]
[USER bool]
[CONSTANT]
[FINAL])
class QMyWidGet : public QWidget
{
Q_OBJECT
Q_PROPERTY(bool focus READ hasFocus)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
Q_PROPERTY(QCursor cursor READ cursor WRITE SetCursor RESET unsetCursor)
public:
explicit QMyWidget(QWidget *parent = nullptr);
};
setProperty可以在运行时为类定义一个新的属性,称之为动态属性。
QPushButton *button = new QPushButton;
QObject *object = button;
object->setProperty("flat", true);
bool isFalt = object->property("flat");
Q_OBJECT
Q_CLASSINFO("author", "ZhangSan")
Q_CLASSINFO("compay", "XXX")
Q_CLASSINFO("version"' "1.1.1")
QMyWidget *myWidget = new QMyWidget;
QDebug()<<myWidget->metaObject()->classInfo(0).name();
QDebug()<<myWidget->metaObject()->classInfo(0).value();
QDebug()<<myWidget->metaObject()->classInfo(1).name();
QDebug()<<myWidget->metaObject()->classInfo(1).value();
static QMetaObject::Connection connect(const QObject *sender,
const char *signal,
const QObject *receiver,
const char *member, Qt::ConnectionType = Qt::AutoConnection);
static QMetaObject::Connection connect(const QObject *sender,
const QMetaMethod &signal,
const QObject *receiver,
const QMetaMethod &method,
Qt::ConnectionType type = Qt::AutoConnection);
inline QMetaObject::Connection connect(const QObject *sender,
const char *signal,
const char *member,
Qt::ConnectionType type = Qt::AutoConnection) const;
最后一个参数Qt::ConnectionType表示信号与槽之间的关联方式
// 如果信和槽函数都带有参数,需要注明参数类型
connect(spinFontSize, SIGNAL(valueChanged(int)), this,
SLOT(on_spinBoxFontSize_valueChanged(int)));
// 当信号名称(包括参数)唯一时,可以使用以下绑定
connect(spinFontSize, &QSpinBox::valueChanged, this,
MainWindow::on_spinBoxFontSize_valueChanged);
在槽函数里,使用QObject::sender()可以回去信号发射者的指针
QSpinBox *spinbox = qobject_cast<QSpinBos*>(sender());
class QPersen : public QObject
{
Q_OBJECT
private:
int m_age = 10;
public:
voud incAge();
signals:
void ageChanged(int value); // 信号函数
};
void QPerson::incAge()
{
m_age++;
emit ageChanged(m_age); //发射信号
}
信号函数必须无返回值,但可以由输入参数,信号函数无需实现,只需要在某些条件下发射信号。
#ifndef QPERSON_H
#define QPERSON_H
#include <QObject>
class QPerson : public QObject
{
Q_OBJECT
Q_CLASSINFO("author", "liutt")
Q_CLASSINFO("compay", "XXX")
Q_CLASSINFO("version", "1.1.1")
// 添加属性
Q_PROPERTY(unsigned age READ age WRITE setAge NOTIFY ageChanged)
Q_PROPERTY(QString name MEMBER m_strName) //MEMBER 绑定变量
Q_PROPERTY(int score MEMBER m_nScore)
private:
unsigned int m_nAge = 10;
QString m_strName;
int m_nScore = 79;
public:
explicit QPerson(QString strName, QObject *parent = nullptr);
unsigned int age();
void setAge(unsigned int value);
void incAge();
signals:
void ageChanged(unsigned int value);
public slots:
};
#endif // QPERSON_H
#include "qperson.h"
QPerson::QPerson(QString strName, QObject *parent) : QObject(parent)
{
m_strName = strName;
}
unsigned int QPerson::age()
{
return m_nAge;
}
void QPerson::setAge(unsigned int value)
{
m_nAge = value;
emit(ageChanged(m_nAge));
}
void QPerson::incAge()
{
m_nAge++;
emit(ageChanged(m_nAge));
}
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "qperson.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
private:
void on_ageChanged(unsigned int value);
private slots:
void on_btnBoyInc_clicked();
void on_btnGirlInc_clicked();
void on_btnClassInfo_clicked();
void on_spin_valueChanged(int value);
private:
Ui::Widget *ui;
QPerson *boy;
QPerson *girl;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QMetaClassInfo>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
ui->spinBoxBoy->setProperty("isBoy", true);
ui->spinBoxGirl->setProperty("isBoy", false);
boy = new QPerson("小乐");
boy->setProperty("score", 60);
boy->setProperty("age", 12);
boy->setProperty("sex", "boy");
connect(boy, &QPerson::ageChanged, this, &Widget::on_ageChanged);
girl = new QPerson("小美");
girl->setProperty("score", 70);
girl->setProperty("age", 11);
girl->setProperty("sex", "girl");
connect(girl, &QPerson::ageChanged, this, &Widget::on_ageChanged);
ui->spinBoxBoy->setValue(12);
ui->spinBoxGirl->setValue(11);
connect(ui->spinBoxBoy, SIGNAL(valueChanged(int)), this, SLOT(on_spin_valueChanged(int)));
connect(ui->spinBoxGirl, SIGNAL(valueChanged(int)), this, SLOT(on_spin_valueChanged(int)));
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_spin_valueChanged(int value)
{
Q_UNUSED(value)
QSpinBox *spinBox = qobject_cast<QSpinBox*>(sender());
if(spinBox->property("isBoy").toBool()) {
boy->setAge(spinBox->value());
}
else {
girl->setAge(spinBox->value());
}
}
void Widget::on_ageChanged(unsigned int value)
{
Q_UNUSED(value)
QPerson *pPerson = qobject_cast<QPerson*>(sender());
QString strName = pPerson->property("name").toString();
QString strSex = pPerson->property("sex").toString();
unsigned int nAge = pPerson->age();
ui->plainTextEdit->appendPlainText(strName+","+strSex+QString::asprintf(",年龄=%d", nAge));
}
void Widget::on_btnBoyInc_clicked()
{
boy->incAge();
}
void Widget::on_btnGirlInc_clicked()
{
girl->incAge();
}
void Widget::on_btnClassInfo_clicked()
{
const QMetaObject* meta = boy->metaObject();
ui->plainTextEdit->clear();
ui->plainTextEdit->appendPlainText("类元对象信息");
ui->plainTextEdit->appendPlainText(QString("类名称:%1").arg(meta->className()));
ui->plainTextEdit->appendPlainText("property: ");
for (int i = meta->propertyOffset(); i < meta->propertyCount(); ++i) {
QMetaProperty prop = meta->property(i);
const char *propName = prop.name();
QString strPropValue = boy->property(propName).toString();
ui->plainTextEdit->appendPlainText(
QString("属性名称:%1,属性值:%2").arg(
propName, strPropValue));
}
ui->plainTextEdit->appendPlainText("classInfo: ");
for (int i = meta->classInfoOffset(); i < meta->classInfoCount(); ++i) {
QMetaClassInfo classInfo = meta->classInfo(i);
ui->plainTextEdit->appendPlainText(
QString("类信息名称:%1,类信息值:%2").arg(
classInfo.name(), classInfo.value()));
}
}
<QtGlobal>头文件包含了Qt类库的一些全局定义:
typedef signed char qint8; /* 8 bit signed */
typedef unsigned char quint8; /* 8 bit unsigned */
typedef short qint16; /* 16 bit signed */
typedef unsigned short quint16; /* 16 bit unsigned */
typedef int qint32; /* 32 bit signed */
typedef unsigned int quint32; /* 32 bit unsigned */
typedef long long qint64; /* 64 bit signed */
typedef unsigned long long quint64; /* 64 bit unsigned */
QT_VERSION 数值版本
QT_VERSION_CHECK() // QT_VERSION_CHECK(5,0,0)
Q_BYTE_ORDER // 系统内存字节序
Q_BIG_ENDIAN // 大端字节序
Q_LITTLE_ENDIAN // 小端字节序
Q_DECL_IMPORT // 共享库导入
Q_DECL_EXPORT // 共享库导出
Q_DECL_OVERRIDE // 用于重载虚函数,没有被重载则报错
Q_DECL_FINAL // 虚函数定义为最终级别,不能被重载
Q_UNUSED(name) // 在函数中定义不在函数中使用的参数
foreach(variable, container) // 用于容器遍历
forever //构造一个无线循环
qDebug(const char* message, ...) // 输出日志,格式化
Qt的容器类比STL中的容器类更轻巧,安全和易用
顺序容器:QList(下标索引),QLinkKedList(不支持下标索引),QVector,QStack,QQueue
关联容器:QMap,QMultiMqp,QHash,QMultiHash,QSet
容器类 | 只读迭代器 | 迭代器 |
---|---|---|
QList,QQueue | QList::const_iterator | QList::iterator |
QLinkedList | QLinkedList::const_iterator | QLinkedList::iterator |
QVector,QStack | QVector::const_iterator | QVector::iterator |
QSet | QSet::const_iterator | QSet::iterator |
QMap<Key,Value>,QMultiMap<Key,Value> | QMap<Key,Value>::const_iterator | QMap<Key,Value>::iterator |
Qt类的模块可以分为几大类:
Qt Core 其他模块都用的核心非图形类
Qt GUI 设计GUI界面的基础类,包括OpenGL
Qt Multimedia 音频、视频、摄像头和广播功能的类
Qt Multiply Widgets 实现多媒体的界面租界类
Qt Network 实现网络编程更简单和轻便的类
Qt QML 用于QML和JavaScript语言的类
Qt Quick 英语构建具有定制用户界面的动态应用的声明框架
Qt Quick Controls 创建桌面样式用户界面,基于Qt Quick的用户界面控件
Qt Quick Dialogs 用于Qt Quick的系统对话框类型
Qt Quick Layouts 用于Qt Quick2界面元素的布局项
Qt SQL 使用SQL数据库操作
Qt Test 用于应用程序的库进行单元测试的类
Qt Widgets 用于构建GUI界面的C++图形组件类
qmake构建时,Qt GUI模块时自动被加入项目的,如果项目不适用GUI功能,使用以下指令取消
QT-=gui
其他模块一般不会被自动加入,在项目使用到某个模块,可以在项目配置中添加:
QT+=sql
QT+=multimedia multimediawidgets
Qt Designer 用于扩展Qt Designer的类
Qt Help 在应用程序中继承在线文档
QtUI Tools 操作Qt Designer生成的窗体的类