QT6(18)3.3.6 测试元对象系统:本节的源代码整理,及源码

(58)先给出本节窗体的生成逻辑整理:

在这里插入图片描述

++介绍生成窗体的关键代码 ui_widget.h

在这里插入图片描述

++上面的文件太大了,下图给出其成员函数

在这里插入图片描述

++ 接着给出另一个重要的成员函数

在这里插入图片描述

++给出本文件的源代码,彩色化效果没有 QT 的好,这会影响阅读效果。所以也是直接采用图片的原因

/********************************************************************************
** Form generated from reading UI file 'widget.ui'  本源文件叫 UI_widget.h 
**
** Created by: Qt User Interface Compiler version 6.2.4
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_WIDGET_H
#define UI_WIDGET_H

#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPlainTextEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QSpinBox>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_Widget
{
public: //本类有数据成员及两个成员函数,但没有构造函数与析构函数
    QVBoxLayout    * verticalLayout;
    QGridLayout    * gridLayout    ;
    QLabel         * label  ;
    QLabel         * label_2;

    QSpinBox       * spinBox_boy ;
    QSpinBox       * spinBox_girl;

    QPushButton    * bnBoyAdd ;
    QPushButton    * bnGirlAdd;

    QPushButton    * bnPrintMeta;
    QPushButton    * bnClearText;

    QPlainTextEdit * plainTextEdit;
    
    void setupUi(QWidget * Widget) //此形参就是本项目中的窗体对象
    {   //const char * QMetaObject::className() const;
        //QString QObject::objectName() const; 返回值不一样
        if (Widget->objectName().isEmpty()) //bool QString::isEmpty() const
            Widget->setObjectName(QString::fromUtf8("Widget"));
            //void QObject::setObjectName(const QString &name);
            //static QString fromUtf8(const char * utf8, qsizetype size)

        Widget->resize(424, 253); //设置本窗体的大小、宽高

        //class QLayout : public QObject, public QLayoutItem
        //class QBoxLayout  : public QLayout
        //class QVBoxLayout : public QBoxLayout
        //QVBoxLayout::QVBoxLayout(QWidget * parent);
        verticalLayout = new QVBoxLayout(Widget); //此行设置了本窗体的垂直布局
        verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));

        //以下开始生成网格布局并填充之,并生成文本框,并全加入窗体的垂直布局
        gridLayout = new QGridLayout();
        gridLayout->setObjectName(QString::fromUtf8("gridLayout"));

        label = new QLabel(Widget); //生成标签对象并加入网格布局
        label->setObjectName(QString::fromUtf8("label"));//存储对象名
        //void QGridLayout::addWidget(QWidget *, int row, int column,
        //  int rowSpan, int columnSpan, Qt::Alignment = Qt::Alignment());
        gridLayout->addWidget(label, 0, 0, 1, 1);//rowSpan 指占据几行,列同

        spinBox_boy = new QSpinBox(Widget); //生成螺旋框并加入网格布局
        spinBox_boy->setObjectName(QString::fromUtf8("spinBox_boy"));
        spinBox_boy->setValue(15);
        gridLayout->addWidget(spinBox_boy, 0, 1, 1, 1);

        bnBoyAdd = new QPushButton(Widget); //生成男增一按钮并加入网格布局
        bnBoyAdd->setObjectName(QString::fromUtf8("bnBoyAdd"));
        gridLayout->addWidget(bnBoyAdd, 0, 2, 1, 1);

        bnPrintMeta = new QPushButton(Widget); //生成打印信息按钮并加入网格布局
        bnPrintMeta->setObjectName(QString::fromUtf8("bnPrintMeta"));
        gridLayout->addWidget(bnPrintMeta, 0, 3, 1, 1);

        label_2 = new QLabel(Widget); //生成女标签并加入网格布局
        label_2->setObjectName(QString::fromUtf8("label_2"));
        gridLayout->addWidget(label_2, 1, 0, 1, 1);

        spinBox_girl = new QSpinBox(Widget); //生成女螺旋框并加入网格布局
        spinBox_girl->setObjectName(QString::fromUtf8("spinBox_girl"));
        spinBox_girl->setValue(17);
        gridLayout->addWidget(spinBox_girl, 1, 1, 1, 1);

        bnGirlAdd = new QPushButton(Widget); //生成女增一按钮并加入网格布局
        bnGirlAdd->setObjectName(QString::fromUtf8("bnGirlAdd"));
        gridLayout->addWidget(bnGirlAdd, 1, 2, 1, 1);

        bnClearText = new QPushButton(Widget); //生成清空按钮并加入网格布局
        bnClearText->setObjectName(QString::fromUtf8("bnClearText"));
        gridLayout->addWidget(bnClearText, 1, 3, 1, 1);

        //将布局添加到盒子的末尾,使用序列拉伸因子拉伸。
        //void QBoxLayout::addLayout(QLayout *layout, int stretch = 0);
        verticalLayout->addLayout(gridLayout);//网格布局被添加入窗体的垂直布局

        plainTextEdit = new QPlainTextEdit(Widget);//添加文本框入垂直布局
        plainTextEdit->setObjectName(QString::fromUtf8("plainTextEdit"));
        verticalLayout->addWidget(plainTextEdit);

        //完成了上面的窗体布局后,由下面的函数填写与设置设置窗体上的可视化文本
        retranslateUi(Widget);

        QMetaObject::connectSlotsByName(Widget);//启用基于控件名的信号槽绑定
    } // setupUi

    void retranslateUi(QWidget *Widget)

    {   //看内容是设置了 UI 界面上各控件的可视化名称,人们可以看到的控件名称
        Widget     ->setWindowTitle(QCoreApplication::translate("Widget", "\345\205\203\345\257\271\350\261\241\347\263\273\347\273\237\345\212\237\350\203\275\344\270\216\345\261\236\346\200\247\346\265\213\350\257\225", nullptr));
        label      ->setText(QCoreApplication::translate("Widget", "\350\256\276\347\275\256\347\224\267\347\224\237\345\271\264\351\276\204", nullptr));
        bnBoyAdd   ->setText(QCoreApplication::translate("Widget", "boy \351\225\277\345\244\247\344\270\200\345\262\201", nullptr));
        bnPrintMeta->setText(QCoreApplication::translate("Widget", "\345\205\203\345\257\271\350\261\241\344\277\241\346\201\257", nullptr));
        label_2    ->setText(QCoreApplication::translate("Widget", "\350\256\276\347\275\256\345\245\263\347\224\237\345\271\264\351\276\204", nullptr));
        bnGirlAdd  ->setText(QCoreApplication::translate("Widget", "girl \351\225\277\345\244\247\344\270\200\345\262\201", nullptr));
        bnClearText->setText(QCoreApplication::translate("Widget", "\346\270\205\347\251\272\346\226\207\346\234\254", nullptr));
    } // retranslateUi

};

namespace Ui { class Widget: public Ui_Widget {}; } // namespace Ui

QT_END_NAMESPACE

#endif // UI_WIDGET_H

(59),开始本项目中的源代码整理,先给出本项目的 qmake 文件

在这里插入图片描述

++**给出头文件 tperson.h **,重新补充了头文件的注释,头文件中的注释更重要:

在这里插入图片描述

++给出头文件

在这里插入图片描述

++给出源文件

在这里插入图片描述

++ 源文件

在这里插入图片描述

++ 开始给出另一个重要的源文件,生成窗体,完善信号与槽

在这里插入图片描述

++以及构造函数

在这里插入图片描述

++ 以及

在这里插入图片描述

++ 以及

在这里插入图片描述

++给出本源文件的完整代码

#include "widget.h"
#include "ui_widget.h"
#include "tperson.h"
#include <QMetaProperty>
#include <QString>

Widget::~Widget() { delete ui; }

void Widget::on_bnBoyAdd_clicked()
{   ptrBoy->incAge();
    // ui->spinBox_boy->setValue(ptrBoy->age());
}

void Widget::on_bnGirlAdd_clicked()
{   ptrGirl->incAge();
    // ui->spinBox_girl->setValue(ptrGirl->age());
}

void Widget::on_bnClearText_clicked()
{   //清空文本框
    ui->plainTextEdit->clear();
}


Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget)
{
    ui->setupUi(this);

    ptrBoy = new TPerson(this,"小明"); //这样就不用显式析构 TPerson 类型了
    ptrBoy->setAge(ui->spinBox_boy->value()); //年龄与螺旋框保持一致
    ptrBoy->setProperty("sex", "boy"); //定义了一个动态属性 sex
    ptrBoy->setProperty("score", 99);  //原来只有 name age score

    ptrGirl = new TPerson(this,"小丽");
    ptrGirl->setAge(ui->spinBox_girl->value());
    ptrGirl->setProperty("sex", "girl");

    ui->spinBox_boy ->setProperty("isBoy", true ); //此同名属性是为了区分
    ui->spinBox_girl->setProperty("isBoy", false); //又一个动态属性

    //void QSpinBox::valueChanged(int);实现由螺旋框引起的年龄改变逻辑
    connect(ui->spinBox_boy, SIGNAL(valueChanged(int)),
            this, SLOT(do_spinChanged(int)));
    connect(ui->spinBox_girl,&QSpinBox::valueChanged,
            this, &Widget::do_spinChanged);//修改年龄为螺旋框中的数据

    connect(ptrBoy , SIGNAL(ageChanged(int)), //年龄改变后更新文本框
            this, SLOT(do_ageChanged(int)));
    connect(ptrGirl, &TPerson::ageChanged, //以下实施信号与槽的连接
            this, &Widget::do_ageChanged); //本函联动文本框以更新学生信息

    //void QSpinBox::valueChanged(int); 此函数是带形参的
    //出现信号与槽函数的重载,则用 qOverload<int,char>(&A::func) 的方式
    connect(ptrBoy , &TPerson::ageChanged, //这是后补充的
            ui->spinBox_boy , &QSpinBox::setValue);
    //void QSpinBox::setValue(int val);
    connect(ptrGirl, &TPerson::ageChanged, //年龄改变后及时更新螺旋框
            ui->spinBox_girl, &QSpinBox::setValue);
}



void Widget::do_ageChanged(int value) //本函作为 incage()的槽函数
{   //本函联动文本框以更新学生信息
    //qobject_cast<T *> 相当于 c++ 的 dynamic_cast<T *>,仅此一个
    TPerson * ptrPerson = qobject_cast<TPerson *>(sender());
    QString name = ptrPerson->property("name").toString();
    QString sex  = ptrPerson->property("sex" ).toString();
    int age = ptrPerson->age();
    int score    = ptrPerson->property("score").toInt();
    QString str  = QString("姓名:%1 ,性别:%2,年龄= %3,成绩= %4")
                .arg(name).arg(sex).arg(age).arg(score);//%1 %2
    ui->plainTextEdit->appendPlainText(str);
}

void Widget::do_spinChanged(int value) //本函作为 spinbox 的槽函数
{   //QObject * QObject::sender() const;
    QSpinBox * ptrSpinbox = qobject_cast<QSpinBox *>(sender());
    if(ptrSpinbox->property("isBoy").toBool()) //表示是男生
        ptrBoy->setAge(value); //此函修正年龄后会触发新的信号与槽函数
    else //QVariant QObject::property(const char * name) const;
        ptrGirl->setAge(value);
}



void Widget::on_bnPrintMeta_clicked()
{   ui->plainTextEdit->clear();
    ui->plainTextEdit->appendPlainText("类名称:");

    const QMetaObject * ptrMetaObject = ptrBoy->metaObject();
    //const char * QMetaObject::className() const;
    ui->plainTextEdit->appendPlainText(  ptrMetaObject->className()  );

    ui->plainTextEdit->appendPlainText("\n属性:");
    for(int i = ptrMetaObject->propertyOffset();
            i < ptrMetaObject->propertyCount() ;  i++ )
    {   //QMetaProperty QMetaObject::property(int index) const;
        QMetaProperty objMetaProperty = ptrMetaObject->property(i);

        const char * name = objMetaProperty.name();

        //QVariant QObject::property(const char * name) const;
        QVariant tmpVariant = ptrBoy->property(name);

        // QString QVariant::toString() const;
        QString strValue = tmpVariant.toString();

        ui->plainTextEdit->appendPlainText(
            QString("属性名:%1,属性值:%2").arg(name).arg(strValue) );                      
    }

    ui->plainTextEdit->appendPlainText("\n类信息(classInfo):");
    //int QMetaObject::classInfoOffset() const;
    for(int i = ptrMetaObject->classInfoOffset() ;
            i < ptrMetaObject->classInfoCount () ;   i++)
    {   //QMetaClassInfo QMetaObject::classInfo(int index) const;
        QMetaClassInfo objClassInfo = ptrMetaObject->classInfo(i);
        ui->plainTextEdit->appendPlainText(
            QString("类信息名:%1,类信息值:%2")                                              
            .arg(objClassInfo.name ()) //const char * QMetaClassInfo::name () const;
            .arg(objClassInfo.value()) //const char * QMetaClassInfo::value() const;  
            );
    }
}

(60)也一并给出前端界面的 搭建效果图,与控件对象的代码名称

在这里插入图片描述

(61)

谢谢

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhangzhangkeji

谢谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值