From cac25277a0b91f899907c29c46c025c56303cccb Mon Sep 17 00:00:00 2001 From: xmuli Date: Mon, 21 Jun 2021 23:41:49 +0800 Subject: [PATCH] feat: Q_OBJECT --- QtQ_OBJECT/QtQ_OBJECT.pro | 21 +++++++++++++ QtQ_OBJECT/m.cpp | 1 + QtQ_OBJECT/m.h | 27 +++++++++++++++++ QtQ_OBJECT/main.cpp | 62 +++++++++++++++++++++++++++++++++++++++ QtSigSlot/QtSigSlot.pro | 24 +++++++++++++++ QtSigSlot/main.cpp | 11 +++++++ QtSigSlot/mainwindow.cpp | 45 ++++++++++++++++++++++++++++ QtSigSlot/mainwindow.h | 24 +++++++++++++++ QtSigSlot/mainwindow.ui | 45 ++++++++++++++++++++++++++++ 9 files changed, 260 insertions(+) create mode 100644 QtQ_OBJECT/QtQ_OBJECT.pro create mode 100644 QtQ_OBJECT/m.cpp create mode 100644 QtQ_OBJECT/m.h create mode 100644 QtQ_OBJECT/main.cpp create mode 100644 QtSigSlot/QtSigSlot.pro create mode 100644 QtSigSlot/main.cpp create mode 100644 QtSigSlot/mainwindow.cpp create mode 100644 QtSigSlot/mainwindow.h create mode 100644 QtSigSlot/mainwindow.ui diff --git a/QtQ_OBJECT/QtQ_OBJECT.pro b/QtQ_OBJECT/QtQ_OBJECT.pro new file mode 100644 index 0000000..67ea643 --- /dev/null +++ b/QtQ_OBJECT/QtQ_OBJECT.pro @@ -0,0 +1,21 @@ +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# You can make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + main.cpp \ + m.cpp + +HEADERS += \ + m.h + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target diff --git a/QtQ_OBJECT/m.cpp b/QtQ_OBJECT/m.cpp new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/QtQ_OBJECT/m.cpp @@ -0,0 +1 @@ + diff --git a/QtQ_OBJECT/m.h b/QtQ_OBJECT/m.h new file mode 100644 index 0000000..6740b43 --- /dev/null +++ b/QtQ_OBJECT/m.h @@ -0,0 +1,27 @@ +#ifndef M_H //要使用元对象系统,需在头文件中定义类。 +#define M_H + +#include //因为要使用 QObject 类,为此需要包含此头文件 +class A:public QObject{ + Q_OBJECT //启动元对象系统,必须声明此宏 +public: + //定义 2 个构造函数、1 个信号、3 个函数。 + Q_INVOKABLE A(){} //要想函数被反射,需要指定 Q_INVOKABLE 宏。 + Q_INVOKABLE A(int){} + Q_INVOKABLE void f(){} + Q_INVOKABLE void g(int i,float j){} + void g1(){} //注意:此函数不会被反射。 + signals: void gb3(); +}; + +class B:public A{ + Q_OBJECT //要使用元对象系统,应在每个类之中都声明此宏 + public: + //定义 1 个函数、2 个信号 +Q_INVOKABLE void f(){} +signals: void gb4(); + void gb5(); +}; + +#endif // M_H + diff --git a/QtQ_OBJECT/main.cpp b/QtQ_OBJECT/main.cpp new file mode 100644 index 0000000..7075a86 --- /dev/null +++ b/QtQ_OBJECT/main.cpp @@ -0,0 +1,62 @@ +#include "m.h" +#include +#include +#include + +using namespace std; +int main(){ + A ma; + B mb; //创建两个对象 + const QMetaObject *pa=ma.metaObject(); + const QMetaObject *pb=mb.metaObject(); + + //以下为通过 QMetaObject 的成员函数获取的信息。 + int j=pa->methodCount(); /*返回对象 ma 中的成员函数数量,包括从父类 QObject 继承而来的 5 个 + 成员函数及本对象中的 2 个成员函数(注意,不包括 g1)、1 个信号,所以 + 总数为 8。*/ + cout<indexOfMethod("g(int,float)"); //获取对象 ma 中的成员函数 g 的索引号。 + cout<constructorCount(); //获取对象 ma 所属类中的构造函数的数量。 + cout<constructorCount(); /*获取对象 mb 所属类 B 中的构造函数的数量,因类 B 无构造函数,所以 + 返回值为 0,此处也可看到,构造函数数量不包含父类的构造函数*/ + cout<indexOfConstructor("A(int)"); //获取对象 ma 所属类中的构造函数 A(int)的索引号。 + cout<indexOfSignal("gb3()"); //获取对象 ma 的信号 gb3()的索引号。 + cout<indexOfSignal("f()"); /*获取对象 ma 的信号 f()的索引号。因为成员函数 f 存在,但不是信 + 号,所以返回值为-1。*/ + cout<methodOffset(); /*获取父类的成员函数数量,包括父类A及QObject中的成员函数,总共为8。 + */ + cout<method(pa->indexOfMethod("g(int,float)")); + QByteArray s= m.name(); //获取成员函数 g 的函数名。 + cout< q=m.parameterNames(); //获取函数 g 的参数名列表 + cout< + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + return a.exec(); +} diff --git a/QtSigSlot/mainwindow.cpp b/QtSigSlot/mainwindow.cpp new file mode 100644 index 0000000..f159348 --- /dev/null +++ b/QtSigSlot/mainwindow.cpp @@ -0,0 +1,45 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" + +#include +#include + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) +{ + ui->setupUi(this); + + setWindowTitle(tr("信号和槽:Qt4 与 Qt5 用法")); + ui->pushButton->setText(tr("关闭窗口")); + + // Qt4 方式 +// connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(closeWindow())); // 式1 +// connect(ui->pushButton, SIGNAL(clicked()), SLOT(closeWindow())); // 式2 + + // Qt5 方式 + connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::closeWindow); // 式3 +// connect(ui->pushButton, &QPushButton::clicked, [=](){ // 式4 +// close(); +// }); +// connect(ui->pushButton, ui->pushButton->metaObject()->method(34), this, this->metaObject()->method(25)); // 式5 + + + +// for (int var = 0; var < metaObject()->methodCount(); ++var) { +// QMetaMethod qm1 = ui->pushButton->metaObject()->method(var); +// QMetaMethod qm2 = this->metaObject()->method(var); +// qDebug()< + +QT_BEGIN_NAMESPACE +namespace Ui { class MainWindow; } +QT_END_NAMESPACE + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + +private slots: + void closeWindow(); + +private: + Ui::MainWindow *ui; +}; +#endif // MAINWINDOW_H diff --git a/QtSigSlot/mainwindow.ui b/QtSigSlot/mainwindow.ui new file mode 100644 index 0000000..a4825b5 --- /dev/null +++ b/QtSigSlot/mainwindow.ui @@ -0,0 +1,45 @@ + + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + MainWindow + + + + + + 240 + 110 + 141 + 71 + + + + 关闭窗口 + + + + + + + 0 + 0 + 800 + 21 + + + + + + + +