当前位置: 首页 > news >正文

中小企业网站建设与推广分析无锡室内设计公司

中小企业网站建设与推广分析,无锡室内设计公司,西宁市网站建设多少钱,做物流网站的公司Qt元对象系统 day5 内存管理 QObject以对象树的形式组织起来#xff0c;当为一个对象创建子对象时#xff0c;子对象回自动添加到父对象的children()列表中。父对象拥有子对象所有权#xff0c;比如父对象可以在自己的析构函数中删除它的孩子对象。使用findChild()或findC…Qt元对象系统 day5 内存管理 QObject以对象树的形式组织起来当为一个对象创建子对象时子对象回自动添加到父对象的children()列表中。父对象拥有子对象所有权比如父对象可以在自己的析构函数中删除它的孩子对象。使用findChild()或findChildren()通过名字和类型查询孩子对象 QObject(QObject *parent nullptr)QObject及其派生类的对象如果其parent非nullptr那么其parent析构时会析构该对象。 父子关系父对象、子对象、父子关系。这是Qt中所特有的与类的继承关系无关传递参数是与parent有关基类、派生类或父类、子类这是对于派生体系来说的与parent无关。 在Qt中最基础和核心的类是QObjectQObject内部有一个名为children的QObjectList列表会保存所有子对象还有一个指针parent用来指向父对象当自己析构时会先把自己从parent列表中删除并且析构所有的children。 #include QApplication #include QWidget #include QPushButton #include QRadioButton//只有在debug模式下才显示调试窗口如果在release模式下不显示调试窗口 #ifdef _DEBUG#pragma comment(linker,/subsystem:console /entry:mainCRTStartup) #else#pragma comment(linker,/subsystem:windows /entry:mainCRTStartup) #endif // _DEBUGint main(int argc, char* argv[]) {QApplication a(argc, argv);QWidget w;{QRadioButton* rBtn new QRadioButton(男, w);//设置对象名rBtn-setObjectName(man_rBtn);auto btn new QPushButton(小瓜);//设置对象名btn-setObjectName(小瓜_大瓜);//如果指定了父对象则不需要手动showbtn-setParent(w);rBtn-move(100, 0);QObject::connect(btn, QPushButton::clicked, [](){qDebug() 小瓜;});//获取btn的父对象auto parentw dynamic_castQWidget*(btn-parent());//是否获取成功if (parentw){qDebug() parentw;}//获取子对象列表const QObjectList list w.children();for (auto v : list){qDebug() v;}//查找指定类型的子对象qDebug() sub object w.findChildQPushButton*();//查找指定的子对象名的子对象qDebug() w.findChildQWidget*(小瓜_大瓜);}//把所有子对象添加到窗口之后再显示窗口w.show();return a.exec(); }运行结果 释放内存 Qt里面有些还是得手动释放 #include QApplication #include QWidget #include QPushButton #include QRadioButton//只有在debug模式下才显示调试窗口如果在release模式下不显示调试窗口 #ifdef _DEBUG#pragma comment(linker,/subsystem:console /entry:mainCRTStartup) #else#pragma comment(linker,/subsystem:windows /entry:mainCRTStartup) #endif // _DEBUGint main(int argc, char* argv[]) {QApplication a(argc, argv);auto w new QWidget;w-show();QObject::connect(w, QObject::destroyed, []() {qDebug() 释放成功;});int ret a.exec();//1.直接使用delete释放(对于直接或间接继承QObject的类对象)delete w;//2.使用QOBject提供的安全释放的函数来释放对象(下一次运行到事情循环的时候才去释放对象)//w-deleteLater(); //此处场景不能使用因为事件循环已经结束了当某个窗口不需要的时候就释放掉用这个return ret; } 运行结果 Qt中的智能指针 为了管理内存等资源C程序员通常采用RAII(Resource Acquisition Is Initialization)机制在类的构造函数中申请资源然后使用最后在析构函数中释放资源。如果没有智能指针程序员必须保证new对象能在正确的时机delete四处编写异常捕获代码以释放资源而智能指针则可以在退出作用域时(不管是正常流程离开或是因异常离开)总调用delete来析构在堆上动态分配的对象。Qt中的智能指针 智能指针描述QPointer[QObject专享指针]QObject或子类对象释放时会自动指向nullptrQScopedPointer[独享指针]超出作用域自动释放管理的对象QSharedPointer[共享指针]QWeakPointer[监视指针]QScopedArrayPointer[独享数组指针]超出作用域自动释放管理的对象数组QSharedDataPointer[隐式共享指针]读时共享写时拷贝QExplicitlySharedDataPointer[显示共享指针]读时共享写时需要手动拷贝(通过detach()函数) QPointer 受保护指针QPointer的行为类似于普通c指针T *只是当被引用的对象被销毁时它会自动清除(不像普通c指针在这种情况下它会变成“悬浮指针”)。T必须是QObject的子类。 #include QApplication #include QWidget #include QPushButton #include QRadioButton #include QPointer //只有在debug模式下才显示调试窗口如果在release模式下不显示调试窗口 #ifdef _DEBUG#pragma comment(linker,/subsystem:console /entry:mainCRTStartup) #else#pragma comment(linker,/subsystem:windows /entry:mainCRTStartup) #endif // _DEBUGclass Text :public QWidget {Q_OBJECT public:Text(QWidget* parent nullptr) :QWidget(parent){text_QPointer();}void text_QPointer(){//QPointer不会自动释放保存的对象QPointer btn new QPushButton(小瓜, this);if (btn){qDebug() 小瓜;}delete btn;//释放之后btn会自动变为nullptrif (!btn){qDebug() 小瓜不见了;}} };int main(int argc, char* argv[]) {QApplication a(argc, argv);Text w;w.show();return a.exec();}#include main.moc运行结果 QScopedPointer 手动管理堆分配对象非常困难而且容易出错通常的结果是代码泄漏内存并且难以维护。QScopedPointer是一个小型实用程序类它通过将基于堆栈的内存所有权分配给堆分配(更通常称为资源获取初始化(RAII))极大地简化了这一点。 QScopedPointer保证当当前作用域消失时所指向的对象将被删除。 QSharedPointer QSharedPointer是c中的一个自动共享指针。它的行为和普通指针完全一样。 如果没有其他QSharedPointer对象引用它当它超出作用域时QSharedPointer将删除它所持有的指针。 QSharedPointer对象可以从一个普通指针、另一个QSharedPointer对象或通过将QWeakPointer对象提升为强引用来创建。 QWeakPointer 在c中QWeakPointer是对指针的自动弱引用。它不能用于直接解引用该指针但可以用于验证该指针是否已在另一个上下文中被删除。 QWeakPointer对象只能通过从QSharedPointer赋值来创建。 QScopedArrayPointer QScopedArrayPointer是一个QScopedPointer默认使用delete[]操作符删除它所指向的对象。为了方便它还提供了操作符[] QSharedDataPointer QSharedDataPointer类表示指向隐式共享对象的指针。 QSharedDataPointer使您可以轻松地编写自己的隐式共享类。QSharedDataPointer实现了线程安全的引用计数确保将QSharedDataPointer添加到可重入类中不会使它们不可重入。 许多Qt类都使用隐式共享以将指针的速度和内存效率与类的易用性结合起来。有关更多信息请参见共享类页面。 假设您想让Employee类隐式共享。这个过程是:定义Employee类使其拥有类型为QSharedDataPointer的单个数据成员。 定义从QSharedData派生的EmployeeData类以包含通常放入Employee类中的所有数据成员。 QExplicitlySharedDataPointer QExplicitlySharedDataPointer类表示指向显式共享对象的指针。 QExplicitlySharedDataPointer使您可以轻松编写自己的显式共享类。QExplicitlySharedDataPointer实现了线程安全的引用计数确保将QExplicitlySharedDataPointer添加到可重入类中不会使它们不可重入。 除了一个很大的区别QExplicitlySharedDataPointer就像QSharedDataPointer。最大的区别是QExplicitlySharedDataPointer的成员函数在允许修改共享数据对象之前不像QSharedDataPointer的非const成员那样在写操作(detach())时自动复制。有一个detach()函数可用但如果您真的想要detach()则必须自己调用它。这意味着QExplicitlySharedDataPointers的行为与常规的c指针类似只是通过进行引用计数并且在引用计数为0之前不删除共享数据对象避免了悬浮指针的问题。 属性系统 Qt提供了一个复杂的属性系统类似于一些编译器供应商提供的属性系统。然而作为一个独立于编译器和平台的库Qt不依赖于像__property或[property]这样的非标准编译器特性。Qt解决方案可以在Qt支持的每一个平台上使用任何标准的c编译器。它基于元对象系统也通过信号和插槽提供对象间通信。 属性的行为类似于类数据成员但它具有通过元对象系统访问的附加特性。 #include QApplication #include QWidget #include QPushButton #include QRadioButton #include QPointer //只有在debug模式下才显示调试窗口如果在release模式下不显示调试窗口 #ifdef _DEBUG#pragma comment(linker,/subsystem:console /entry:mainCRTStartup) #else#pragma comment(linker,/subsystem:windows /entry:mainCRTStartup) #endif // _DEBUGclass Person :public QObject {Q_OBJECT public:Person(){} };int main(int argc, char* argv[]) {QApplication a(argc, argv);Person xiaogua;//1.通过方法设置一些成员变量xiaogua.setObjectName(小瓜);qDebug() xiaogua.objectName();//2.通过属性来设置xiaogua.setProperty(objectName, 大瓜);qDebug() xiaogua.objectName() xiaogua.property(objectName);//3.如果设置类里面没有的属性,那么则会添加临时的属性xiaogua.setProperty(name, 小瓜);xiaogua.setProperty(age, 21);qDebug() xiaogua.property(name) xiaogua.property(age);return a.exec();} #include main.moc运行结果 声明自己的属性 除了通过setProperty动态添加属性之外怎样才能在代码中声明属性呢 要声明属性请在继承 QObject 的类中使用 Q_PROPERTY() 宏。 Q_PROPERTY(type name(READ getFunction [WRITE setFunction] |MEMBER memberName [(READ getFunction | WRITE setFunction)])[RESET resetFunction][NOTIFY notifySignal][REVISION int | REVISION(int[, int])][DESIGNABLE bool][SCRIPTABLE bool][STORED bool][USER bool][BINDABLE bindableProperty][CONSTANT][FINAL][REQUIRED])如果未指定 MEMBER 变量则需要 READ 访问器函数。 它用于读取属性值。 理想情况下const 函数用于此目的它必须返回属性的类型或对该类型的 const 引用。 例如QWidget::focus 是一个带有 READ 函数的只读属性QWidget::hasFocus()。 WRITE 访问器函数是可选的。 它用于设置属性值。 它必须返回 void 并且必须只接受一个参数该参数可以是属性的类型也可以是指向该类型的指针或引用。 例如QWidget::enabled 具有 WRITE 函数 QWidget::setEnabled()。 只读属性不需要 WRITE 函数。 例如QWidget::focus 没有 WRITE 功能。 如果未指定 READ 访问器函数则需要 MEMBER 变量关联。 这使得给定的成员变量可读可写而无需创建 READ 和 WRITE 访问器函数。 如果您需要控制变量访问除了 MEMBER 变量关联之外仍然可以使用 READ 或 WRITE 访问器函数。 RESET 功能是可选的。 它用于将属性设置回其特定于上下文的默认值。 例如QWidget::cursor 有典型的 READ 和 WRITE 函数QWidget::cursor() 和 QWidget::setCursor()它还有一个 RESET 函数QWidget::unsetCursor()因为没有调用 QWidget:: setCursor() 可以表示重置为特定于上下文的光标。 RESET 函数必须返回 void 并且不带任何参数。 NOTIFY 信号是可选的。 如果已定义则应指定该类中的一个现有信号该信号在属性值更改时发出。 MEMBER 变量的 NOTIFY 信号必须采用零个或一个参数该参数必须与属性的类型相同。 该参数将采用属性的新值。 NOTIFY 信号只应在属性真正被更改时发出以避免在 QML 中不必要地重新评估绑定例如。 当没有显式设置器的 MEMBER 属性需要时Qt 会自动发出该信号。 REVISION 编号或 REVISION() 宏是可选的。 如果包含它定义了要在 API 的特定修订版中使用的属性及其通知信号通常用于暴露于 QML。 如果不包含则默认为 0。 DESIGNABLE 属性指示该属性是否应在 GUI 设计工具例如 Qt Designer的属性编辑器中可见。 大多数属性都是可设计的默认为 true。 有效值为真和假。 SCRIPTABLE 属性指示脚本引擎是否可以访问此属性默认为 true。 有效值为真和假。 STORED 属性指示该属性是否应该被认为是独立存在的或者取决于其他值。 它还指示在存储对象的状态时是否必须保存属性值。 大多数属性是 STORED 的默认为 true但例如QWidget::minimumWidth() 的 STORED 为 false因为它的值只是从属性 QWidget::minimumSize() 的宽度分量中获取的它是一个 QSize。 USER 属性指示该属性是被指定为该类的面向用户的属性还是用户可编辑的属性。 通常每个类只有一个 USER 属性默认为 false。 例如QAbstractButton::checked 是可检查按钮的用户可编辑属性。 请注意QItemDelegate 获取和设置小部件的 USER 属性。 BINDABLE bindableProperty 属性表明该属性支持绑定并且可以通过元对象系统 (QMetaProperty) 设置和检查与该属性的绑定。 bindableProperty 命名 QBindable 类型的类成员其中 T 是属性类型。 这个属性是在 Qt 6.0 中引入的。 CONSTANT 属性的存在表明属性值是常量。 对于给定的对象实例常量属性的 READ 方法在每次调用时都必须返回相同的值。 对于对象的不同实例该常数值可能不同。 常量属性不能有 WRITE 方法或 NOTIFY 信号。 FINAL 属性的存在表明该属性不会被派生类覆盖。 这在某些情况下可用于性能优化但并非由 moc 强制执行。 必须注意永远不要覆盖 FINAL 属性。 REQUIRED 属性的存在表明该属性应该由该类的用户设置。 这不是由 moc 强制执行的并且对于暴露给 QML 的类最有用。 在 QML 中除非设置了所有 REQUIRED 属性否则无法实例化具有 REQUIRED 属性的类。 #include QApplication #include QWidget #include QPushButton #include QRadioButton #include QPointer //只有在debug模式下才显示调试窗口如果在release模式下不显示调试窗口 #ifdef _DEBUG#pragma comment(linker,/subsystem:console /entry:mainCRTStartup) #else#pragma comment(linker,/subsystem:windows /entry:mainCRTStartup) #endif // _DEBUG int g_tel666; class Person :public QObject {Q_OBJECT//让成员变量暴露给属性Q_PROPERTY(QString name MEMBER m_name NOTIFY nameChanged)Q_PROPERTY(int age MEMBER m_age NOTIFY ageChanged)//直接定义属性Q_PROPERTY(quint64 tel READ getTel WRITE setTel RESET resetTel NOTIFY telChanged)public:Person(){}//提供接口int age()const{ return m_age;}void setAge(int age) { m_age age; }QString name() const { return m_name; }void setName(const QString name) { m_name name; }quint64 getTel()const { return g_tel; }void setTel(quint64 tel){if (g_tel ! tel){g_tel tel;emit telChanged(tel);}}void resetTel() { setTel(-1); }signals:void telChanged(quint64 tel);void ageChanged(int age);void nameChanged();protected:int m_age{};QString m_name{}; };int main(int argc, char* argv[]) {QApplication a(argc, argv);Person xiaogua;xiaogua.setName(小瓜);xiaogua.setAge(20);QObject::connect(xiaogua, Person::telChanged, [](quint64 tel){qDebug() tel changed tel;});QObject::connect(xiaogua, Person::ageChanged, [](){qDebug() age changed;});QObject::connect(xiaogua, Person::nameChanged, [](){qDebug() name changed;});//xiaogua.setTel(12345678);xiaogua.setProperty(tel, QVariant());xiaogua.setAge(21);xiaogua.setProperty(name, ccc);qDebug() xiaogua.property(name) xiaogua.property(age) xiaogua.property(tel);return a.exec();} #include main.moc运行结果 绑定属性 Qt提供了可绑定属性。可绑定属性是具有值或使用任何c函数(通常是c lambda表达式)指定的属性。如果它们是使用c函数指定的那么当它们的依赖项发生变化时它们就会自动更新。 #include QApplication #include QWidget #include QPushButton #include QRadioButton #include QPointer #includeQProperty #includeQObjectBindableProperty //只有在debug模式下才显示调试窗口如果在release模式下不显示调试窗口 #ifdef _DEBUG#pragma comment(linker,/subsystem:console /entry:mainCRTStartup) #else#pragma comment(linker,/subsystem:windows /entry:mainCRTStartup) #endif // _DEBUG//1,在Qobject子类中使用绑定属性 struct Circle : public QObject {Q_OBJECT public:Circle(){//添加绑定area.setBinding([]{return M_PI * radius * radius;});}//QPropertyint radius{};//QPropertyqreal area{};signals:void radiusChanged();void areaCahnged(); public:Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(Circle, int, radius, 0, Circle::radiusChanged);Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(Circle, qreal, area, 0, Circle::areaCahnged); }; //2,如果类没有继承自Qobject struct Rect {Rect(){area.setBinding([]{return w * h;});}QPropertyint w;QPropertyint h;QPropertyint area; };int main(int argc, char* argv[]) {QApplication a(argc, argv);Circle c;QObject::connect(c, Circle::areaCahnged, []{qDebug() areaChange;});c.radius 23;qDebug() c.area;Rect r;r.w 5;r.h 9;qDebug() r.area;return a.exec(); }#include main.moc内省机制 所谓内省是指面向对象语言的一种在运行期间查询对象信息的能力 比如如果该语具有运行期间检查对象型别的能力那么我们称它是型别内省type intropection的型别内省可以用来实施多态。Qt拓展了C的内省机制实际上它并没有采用C的RTTI),而是提供了更为强大的元对象(meta object)机制来实现内省。接下来就让我们看看Qt是如何扩展c内省机制的。要深刻理解Qt的内省机制首先理解QObjectQObject类是整个Qt对象模型的心脏Qt对象模型最为核心的功能是提供一种无缝的对象通讯机制即就是我们所熟知的信号和槽。QObject主要有三大职责 内存管理、内省(intropection)与事件处理。本文将集中在在内省的讨论。以下代码介绍了QObject类提供的内省方法: //判断该类是否继承自指定的类 bool inherits(const char *className) const;QWidget* w new QWidget; w.inherits(QObject); //true w.inherits(QWidget); //false示例 #includeQApplication #includeQWidget #includeQMetaEnum class Test { public:Test(){QWidget w;qDebug() w.inherits(QObject);auto metaObject w.metaObject();qDebug()metaObject-className();} };//1,在命名空间中使用注册枚举 namespace Maye {Q_NAMESPACEenum Type{Player,Enemy,Bullet};Q_ENUM_NS(Type) //把枚举类型注册到元对象系统 } //2在类中注册枚举 struct Person : public QObject {Q_OBJECT public:enum Identity{Student,Doctor,Teacher};Q_ENUM(Identity) }; int main(int argc, char* argv[]) {QApplication a(argc, argv);Test t;using namespace Maye;Type type Player;qDebug() type; //0 PlayerPerson::Identity id Person::Doctor;qDebug() id;//获取枚举信息QMetaEnum me QMetaEnum::fromTypePerson::Identity();qDebug() me.name() me.keyCount();qDebug() me.keyToValue(Teacher);qDebug() me.valueToKey(Person::Doctor);return a.exec(); } #include main.mocQFlags #includeQApplication #includeQFlags struct xiaogua : public QObject {Q_OBJECT public:enum AlignMent{Top 1,Left 1 2,Bottom 1 3,Right 1 4,Center 1 5};Q_ENUMS(AlignMent)Q_DECLARE_FLAGS(AlignMentFlags, AlignMent)Q_FLAG(AlignMentFlags) };int main(int argc, char* argv[]) {QApplication a(argc, argv);xiaogua::AlignMentFlags flags(xiaogua::Top | xiaogua::Left);if (flags.testFlag(xiaogua::Top)){qDebug() has top;}if (flags.testFlag(xiaogua::Left)){qDebug() has left;}return a.exec(); } #include main.moc运行结果
http://www.dnsts.com.cn/news/216161.html

相关文章:

  • 试卷网站在线做做食品的采购员常用网站
  • 这几年做那个网站致富松江手机网站建设
  • 网站开发专业前景wordpress添加备案号插件
  • 深圳集团网站建设海报设计图
  • 网站用ps做还是aiwordpress 摘要长度
  • 一元夺宝网站建设2017wordpress简洁博客主题
  • 建设银行网站首页下载北京 好的网站制作
  • 怎么申请订阅号沈阳seo收费
  • 乐云seo网站建设公司设计网站要多少钱
  • 可以做盗版漫画网站吗设计制作活动主题
  • 外贸网站模板设计军事最新消息今天
  • 推广自身网站深圳市东企网络技术有限公司
  • 辽宁海星建设集团有限公司网站网站设计怎么写
  • 模板网站也需要服务器吗建设电商网站的总结报告
  • 中国建设银行网站公积金查询系统西安seo服务公司
  • 海口cms模板建站网站模版上线需要什么意思
  • 包头怎样做网站如何建设网站视频教程
  • 网站建设需要域名还有什么龙岗建设高端网站
  • 百度收录网站工业设计是机械类还是设计类
  • 巩义专业网站建设公司ps网站专题怎么做
  • 哪个网站可以做房产信息群发小程序开发平台哪种品牌的好
  • 哪些网站可以找到做药人的信息图片如何连接到wordpress
  • 网站页面设计教程登建设厅锁子的是哪个网站
  • 网站开发应该怎么学深圳商城网站
  • pc端移动端网站开发鞍山建站
  • 英文网站建设需要注意的五点问题app软件开发摄像头
  • 广州网站建设oem成都线上推广平台
  • 手机商城网站建设策划方案范文如何用凡科网建立一个网站
  • 表白网站制作源码合肥市住建局官方网
  • 旌阳区黄河开发建设网站企业网站策划文案