QObject_other

2024-01-12 00:36
文章标签 qobject

本文主要是介绍QObject_other,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

QObject

属性定义

自定义属性我用到的较少,只在自定义键盘时用到了。
属性的行为类似于类数据成员,但它们具有可通过元对象系统访问的附加特性

Q_PROPERTY关键字
定义语法:
Q_PROPERTY(type name
(READ getFunction [WRITE setFunction] |
MEMBER memberName [(READ getFunction | WRITE setFunction)])
[RESET resetFunction]
[NOTIFY notifySignal]
[REVISION int]
[DESIGNABLE bool]
[SCRIPTABLE bool]
[STORED bool]
[USER bool]
[CONSTANT]
[FINAL]
[REQUIRED])

#define Q_PROPERTY(...) QT_ANNOTATE_CLASS(qt_property, __VA_ARGS__)class A:public QObject
{Q_OBJECT
public:Q_PROPERTY(QColor color MEMBER m_color NOTIFY colorChanged)Q_PROPERTY(qreal spacing MEMBER m_spacing NOTIFY spacingChanged)Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged)
signals:void colorChanged();void spacingChanged();void textChanged(const QString &newText);private:QColor  m_color;qreal   m_spacing;QString m_text;
}

bool setProperty(const char *name, const QVariant &value)

如果属性是Q_PROPERTY定义的,设置属性值成功返回true,否则返回false
如果属性不是Q_PROPERTY定义的,则动态的新增属性并且返回false

bool QObject::setProperty(const char *name, const QVariant &value)
{Q_D(QObject);const QMetaObject* meta = metaObject();//获取元对象if (!name || !meta)return false;int id = meta->indexOfProperty(name);//元对象中查找静态属性if (id < 0) {if (!d->extraData)d->extraData = new QObjectPrivate::ExtraData;const int idx = d->extraData->propertyNames.indexOf(name);//静态属性没找到,在动态设置的属性里面找if (!value.isValid()) {if (idx == -1)return false;d->extraData->propertyNames.removeAt(idx);d->extraData->propertyValues.removeAt(idx);} else {if (idx == -1) { //动态设置的属性里面也没有找到d->extraData->propertyNames.append(name);//新增属性d->extraData->propertyValues.append(value);//新增属性值} else {//动态设置的属性里面找到了if (value.userType() == d->extraData->propertyValues.at(idx).userType()&& value == d->extraData->propertyValues.at(idx))return false;d->extraData->propertyValues[idx] = value;//修改属性值}}QDynamicPropertyChangeEvent ev(name);QCoreApplication::sendEvent(this, &ev);//发送QDynamicPropertyChangeEvent事件return false;//新增动态属性始终返回false}//静态属性直接修改其值QMetaProperty p = meta->property(id);return p.write(this, value);
}

QList dynamicPropertyNames() const

返回所有使用setProperty动态新增的属性名称列表

int senderSignalIndex()

返回调用当前执行槽的信号的元方法索引,它是sender()返回的类的成员。
应该在槽函数中调用,如果在由信号激活的槽之外调用,则返回-1。
对于带有默认参数的信号,此函数将始终返回带有所有参数的索引,而不管connect()使用了哪个参数。
例如,被销毁的信号(QObject *obj = nullptr)将有两个不同的索引(带参数和不带参数),但这个函数将始终返回带参数的索引。
这不适用于重载具有不同参数的信号。
警告:这个函数违反了面向对象的模块化原则。但是,当许多信号连接到单个槽时,访问信号索引可能很有用。
警告:当通过Qt::DirectConnection从不同于此对象线程的线程调用槽时,此函数的返回值无效。不要在这种场景中使用此函数。
这个函数是在Qt 4.8中引入的。

int receivers(const char* signal) const

返回连接到该信号的接收器的数量。
由于插槽和信号都可以用作信号的接收器,并且可以多次进行相同的连接,因此接收器的数量与从该信号进行连接的数量相同。

if (receivers(SIGNAL(valueChanged(QByteArray))) > 0) {
QByteArray data;
get_the_value(&data); // expensive operation
emit valueChanged(data);
}

bool inherits(const char *classname)

返回是否直接或间接继承了className类,是则返回true;否则返回false。
一个类被认为继承了它自己。
QTimer *timer = new QTimer; // QTimer inherits QObject
timer->inherits(“QTimer”); // returns true
timer->inherits(“QObject”); // returns true
timer->inherits(“QAbstractButton”); // returns false

// QVBoxLayout:public QObject ,public QLayoutItem{};
QVBoxLayout *layout = new QVBoxLayout;
layout->inherits(“QObject”); // returns true
layout->inherits(“QLayoutItem”); // returns true (even though QLayoutItem is not a QObject)

bool isSignalConnected(const QMetaMethod &signal)

如果信号连接到至少一个接收器,则返回true,否则返回false
Signal必须是该对象的信号成员,否则行为未定义。
static const QMetaMethod valueChangedSignal = QMetaMethod::fromSignal(&MyObject::valueChanged);
if (isSignalConnected(valueChangedSignal)) {
QByteArray data;
data = get_the_value(); // expensive operation
emit valueChanged(data);
}

void deleteLater()

计划删除此对象,当控制返回到事件循环时,对象将被删除
如果在调用此函数时事件循环没有运行(例如,在QCoreApplication::exec()之前在对象上调用deleteLater()),则一旦事件循环启动,该对象将被删除。
如果在主事件循环停止后调用deleteLater(),则不会删除对象。
自Qt 4.8以来,如果deleteLater()在没有运行事件循环的线程中的对象上调用,则该对象将在线程结束时被销毁。
注意,进入和离开一个新的事件循环(例如,通过打开一个模态对话框)不会执行延迟删除;对于要删除的对象,控件必须返回到从中调用deleteLater()的事件循环。
注意:多次调用这个函数是安全的;当交付第一个延迟删除事件时,对象的任何挂起事件都将从事件队列中删除。


void QObject::deleteLater()
{QCoreApplication::postEvent(this, new QDeferredDeleteEvent());
}bool QObject::event(QEvent *e)
{case QEvent::DeferredDelete:qDeleteInEventHandler(this);break; 
}void qDeleteInEventHandler(QObject *o)
{delete o;
}

static uint registerUserData()

注册用户数据类型,返回此类型id号

static QBasicAtomicInteger<uint> user_data_registration = Q_BASIC_ATOMIC_INITIALIZER(0);uint QObject::registerUserData()
{return user_data_registration.fetchAndAddRelaxed(1);
}

void setUserData(uint id, QObjectUserData* data)

设置对应id的用户数据类型的数据,数据必须是指针且不需要自己手动释放

void QObject::setUserData(uint id, QObjectUserData* data)
{Q_D(QObject);if (!d->extraData)d->extraData = new QObjectPrivate::ExtraData;if (d->extraData->userData.size() <= (int) id)d->extraData->userData.resize((int) id + 1);d->extraData->userData[id] = data;//用户数据是一个数组,里面保存不同类型的用户数据
}

QObjectUserData* userData(uint id) const

获取用户数据

QObjectUserData* QObject::userData(uint id) const
{Q_D(const QObject);if (!d->extraData)return nullptr;if ((int)id < d->extraData->userData.size())return d->extraData->userData.at(id);return nullptr;
}

userData自动析构

对象析构时自动析构释放所有用户数据

QObjectPrivate::~QObjectPrivate()
{if (extraData)qDeleteAll(extraData->userData);delete extraData;
}template <typename Container>
inline void qDeleteAll(const Container &c)
{qDeleteAll(c.begin(), c.end());
}void qDeleteAll(ForwardIterator begin, ForwardIterator end)
{while (begin != end) {delete *begin;//删除所有用户数据,对于用户数据里面含有指针的类型,有数据本身析构释放++begin;}
}
ainer &c)
{qDeleteAll(c.begin(), c.end());
}void qDeleteAll(ForwardIterator begin, ForwardIterator end)
{while (begin != end) {delete *begin;//删除所有用户数据,对于用户数据里面含有指针的类型,有数据本身析构释放++begin;}
}

这篇关于QObject_other的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/596228

相关文章

QThread 与QObject::moveToThread在UI中的应用

1. QThread的两种用法 第一种用法就是继承QThread,然后覆写 virtual void run(), 这种用法的缺点是不能利用信号槽机制。 第二种用法就是创建一个线程,创建一个对象,再将对象moveToThread, 这种可以充分利用信号槽机制,与UI框架完美融合。这与std::thread也是不一样的地方。 2. moveToThread用法讲解 示例地址:MultiThr

QT QObject::connect函数的学习

转载自http://blog.csdn.net/ybjx111/article/details/8272405 从Qobject(QObject.h)源码中可以看到QObject::connect的定义是这样的: [cpp]  view plain copy static bool connect(const QObject *sender, const char *signa

创建继承自QObject的线程:一个详细指南

目录标题 步骤 1:创建一个新的QObject子类步骤 2:在新的QObject子类中实现工作代码步骤 3:创建一个新的QThread对象步骤 4:管理线程的生命周期步骤 5:处理线程间通信结论 在Qt中,线程可以通过继承QThread类并重写其run()方法来创建。然而,一个更现代的方法是继承QObject并将工作放入一个槽函数中,然后使用QThread::start()来

QT6之多线程——子类化QObject和子类化QThread

备注:本文重点不是教怎么写多线程,这个官方示例依和网上示例一大把。  众所周知QT多线程有两种方法,一个是子类化QThread,另一个是子类化QObject。 Qt官方实际上是推荐后者,但实际运用中两者各有优劣和场景,并没有绝对的替代彼此。 多线程的必要性不言而喻,Qt默认的线程在Qt中称之为窗口线程,也叫主线程,负责窗口事件处理(鼠标事件、键盘事件等等)或者窗口控件数据的更新子线程负责后台

Qt::QObject类

Qt::QObject类   QObject 类是Qt 所有类的基类。   QObject是Qt对象模型的核心。这个模型的中心要素就是一种强大的叫做信号与槽无缝对象沟通机制。你可以用 connect()函数来把一个信号连接到槽,也可以用disconnect()函数来破坏这个连接。为了避免永无止境的通知循环,你可以用blockSignal()函数来暂时阻塞信号。保护函数 connectNoti

Qt | QObject 类中的成员函数存取属性值与动态属性、用反射机制获取属性的信息

1、注册自定义类型与 QMetaType 类 ①、QMetaType 类用于管理元对象系统中命名的类型,该类用于帮助 QVariant 中的类型以及队列中信号和槽的连接。它将类型名称与类型关联,以便在运行时动态创建和销毁该名称。 ②、QMetaType::Type 枚举类型定义了 QMetaType 支持的类型。其原型为 enum Type{void, Bool,Int……Unkno

009.PyQt5_QObject基类_信号与槽函数

信号与槽函数 信号(Signal)就是在特定情况下被发射(emit)的一种通告。 例如一个PushButton按钮最常见的信号就是鼠标单击时发射的clicked()信号,一个ComboBox最常见的信号是选择的项变化时发射的CurrentIndexChanged()信号。GUI程序设计的主要内容就是对界面上各组件发射的特定信号进行响应,只需要知道什么情况下发射了哪些信号,然后合理地去响应和处理这

qt报错“QObject::connect: No such signal *”

槽函数如下: connect(&refresh_data_thread, SIGNAL(GetSecondPageDataSignal(data)),baseline_widget, SLOT(RefreshSecondPageData(data))); 信号emit如下:  现象:如下图,一直告警,No such signal,46行和49行打印都正常,但槽函数就是不打印输出

QObject: Cannot create children for a parent that is in a different thread. (Parent is QLabel(0x2c19

使用PyQt5的时候,在使用多线程的时候,会报错: QObject: Cannot create children for a parent that is in a different thread. (Parent is QLabel(0x2c1964c0ba0), parent’s thread is QThread(0x2c18e6db8e0), current thread is QT

温酒读Qt:QObject中篇2 ——欲遮还羞的 QObjectPrivate

《妙法莲华经》曰:“佛道长远,久受勤苦,乃可得成。” 世事修炼,莫不如是,日拱一卒无有尽,功不唐捐终入海。 传送门: 《温酒读Qt:QObject 序篇》 《温酒读Qt:QObject中篇1—— Q_OBJECT的隐秘角落》 1、QObjectPrivate class 先贴源码,然后我们挑重点进行分析; /*******************************