QObject ——QT所有类的基类

Qt框架中的QObject类是一种基类,Qt中的许多其他类都继承自它 上述代码定义了一个名为MyClass的类,该类继承了QObject类,并声明了一个名为mySignal()的信号和一个名为mySlot()的槽函数。在使用QObject类时,我们还需要注意,其子类必须必须通过QObject或其子类的构造函数进行初始化。元对象系统允许我们在运行时查询对象的属性,调用对象的方法,并且在对象属性改变时接收通知。上述代码中,我们新定义了一个名为MyObject的类,并未通过QObject或其子类的构造函数进行初始化,这是错误的写法。 阅读详情

QObject ——QT所有类的基类

QObject是QT所有类的基类,QObject是Qt Object Model的核心

CODE:

/*
什么是Qt Object Model,主要包括如下的东西
1.信号和槽
2.良好的对象属性,如可查询和很好看,,,~~
  3.有力的事件和事件过滤器
4.国际化字符设计
5.定时器为GUI的事件提供毫秒级的支持
6.很优秀的对象树结构
7.当对象销毁时指针自动设置为0
  8.a dynamic cast that works across library boundaries,不知如何翻译

[Copy to clipboard]

你可以通过connect()连接一个信号到槽,并通过disconnect()来解除这个连接,临时中断用blockSignals(),还可以用 connectNotify()和disconnectNotify()来监听一个连接状态
每个对象有个objectName(),他的类名可以在metaObject() (查阅QMetaObject::className())找到,还可以用inherits()函数来检测他的继承关系
当一个对象销毁时发生信号 destroyed()
更多请参阅 QMetaObject, QPointer, QObjectCleanupHandler, 和Object Trees and Object Ownership.


属性:

1.对象名
objectName : QString
设置函数
QString objectName () const
void setObjectName ( const QString & name )
请参阅 metaObject() 和QMetaObject::className().


成员方法:

1.构造函数
QObject::QObject ( QObject * parent = 0 )
2.虚函数,析构函数
QObject::~QObject () [virtual]
要删除一个类请用deleteLater()代替
请参阅deleteLater()

2.阻塞信号
bool QObject::blockSignals ( bool block )
成功返回true,失败为false
请参阅signalsBlocked()

3.虚保护函数,得到子类的事件
void QObject::childEvent ( QChildEvent * event ) [virtual protected]
请参阅QChildEvent和QEvent类

4.得到子类列表
const QObjectList & QObject::children () const
他在#include<QObject>里面的定义如下:

CODE:
typedef QList<QObject*> QObjectList;
[Copy to clipboard]

first()和last()分别得到子类的第1个和最后一个,同时可以用 QWidget类的 raise()或者lower()来改变,这2个都是槽,注意
请参阅findChild(), findChildren(), parent(), 和setParent()

5.静态连接信号和槽的函数
bool QObject::connect ( const QObject * sender, const char * signal, const QObject * receiver, const char * method, Qt::ConnectionType type = Qt::AutoCompatConnection ) [static]
使用时必须用SIGNAL() 和SLOT()宏指出信号和槽
如:

CODE:
QLabel *label = new QLabel;
QScrollBar *scrollBar = new QScrollBar;
QObject::connect(scroll, SIGNAL(valueChanged(int)),
              label, SLOT(setNum(int)));
[Copy to clipboard]

注意:
a.这里要千万注意,里面的参数不能有变量名,只能有类型,不然不能工作
错误例子:

CODE:
  // WRONG
  QObject::connect(scroll, SIGNAL(valueChanged(int value)),
              label, SLOT(setNum(int value)));
[Copy to clipboard]

b.同样信号可以连接到信号,如:

CODE:
  class MyWidget : public QWidget
  {
    Q_OBJECT

  public:
    MyWidget();

  signals:
    void buttonClicked();

  private:
    QPushButton *myButton;
  };

  MyWidget::MyWidget()
  {
    myButton = new QPushButton(this);
    connect(myButton, SIGNAL(clicked()),
          this, SIGNAL(buttonClicked()));
  }

[Copy to clipboard]

这个例子的意思是,就是MyWidget的构造函数将自己私有成员的信号以另外一种方式传出去,使其有效
c.一个信号可以连到很多信号和槽上,但是一个槽只能连到一个信号上
d.成功返回true,失败false
请参阅disconnect()

6.connect函数2
bool QObject::connect ( const QObject * sender, const char * signal, const char * method, Qt::ConnectionType type = Qt::AutoCompatConnection ) const

7.这个函数检测当有solt连接到这个信号时被调用
void QObject::connectNotify ( const char * signal ) [virtual protected]
请参阅connect() 和disconnectNotify()

8.定义自己的类的行为
void QObject::customEvent ( QEvent * event ) [virtual protected]
请参阅event() 和QEvent类

9.槽,删除此对象
void QObject::deleteLater () [slot]
请参阅destroyed() and QPointer

10.信号,当对象销毁时发生
void QObject::destroyed ( QObject * obj = 0 ) [signal]
请参阅deleteLater() 和QPointer类

11.解除信号和槽的连接
bool QObject::disconnect ( const QObject * sender, const char * signal, const QObject * receiver, const char * method ) [static]
他一般有3种用法
a.解除一个类的所有信号的连接

CODE:
disconnect(myObject, 0, 0, 0);
或者
disconnect(myObject, 0, 0, 0);
[Copy to clipboard]

b.解除一个特定的信号

CODE:
disconnect(myObject, SIGNAL(mySignal()), 0, 0);
或者
myObject->disconnect(SIGNAL(mySignal()));
[Copy to clipboard]

c.解除一个特定的接受对象

CODE:
disconnect(myObject, 0, myReceiver, 0);
或者
myObject->disconnect(myReceiver);
[Copy to clipboard]

0就代表"any signal","any receiving object","any slot in the receiving object",就是所有信号,所有接收对象,一个接收对象的所有槽
注意:第一个参数就是sender不能为0,因为你不能解除所有信号和槽的关系
请参阅connect()

12.disconnect的函数2
bool QObject::disconnect ( const char * signal = 0, const QObject * receiver = 0, const char * method = 0 )

13.disconnect的函数3
bool QObject::disconnect ( const QObject * receiver, const char * method = 0 )

14.解除检测
void QObject::disconnectNotify ( const char * signal ) [virtual protected]
请参阅disconnect() 和connectNotify()

15.显示对象信息,一般用来调试用
void QObject::dumpObjectInfo ()
请参阅dumpObjectTree()

16.显示对象树
void QObject::dumpObjectTree ()
请参阅dumpObjectInfo()

17.检测事件,如果事件是经过验证或者执行过就返回true,否则false
bool QObject::event ( QEvent * e ) [virtual]
请参阅installEventFilter(), timerEvent(), QApplication::sendEvent(), QApplication::postEvent(), 和QWidget::event()

18.事件过滤
bool QObject::eventFilter ( QObject * watched, QEvent * event ) [virtual]
例子:

CODE:
  class MainWindow : public QMainWindow
  {
  public:
    MainWindow();

  protected:
    bool eventFilter(QObject *obj, QEvent *ev);

  private:
    QTextEdit *textEdit;
  };

  MainWindow::MainWindow()
  {
    textEdit = new QTextEdit;
    setCentralWidget(textEdit);

    textEdit->installEventFilter(this);
  }

  bool MainWindow::eventFilter(QObject *obj, QEvent *event)
  {
    if (obj == textEdit) {
        if (event->type() == QEvent::KeyPress) {
          qDebug("Ate key press");
          return true;
        } else {
          return false;
        }
    } else {
        // pass the event on to the parent class
        return QMainWindow::eventFilter(obj, event);
    }
  }
[Copy to clipboard]

在这个例子中只响应textEdit的事件
请参阅installEventFilter()

19.找出子类
T QObject::findChild ( const QString & name = QString() ) const
没有找到返回0,常用的调用
a.找特定的子类

CODE:
QPushButton *button = parentWidget->findChild<QPushButton *>("button1");
[Copy to clipboard]

b.找所有的同一类别子类

CODE:
QListWidget *list = parentWidget->findChild<QListWidget *>();
[Copy to clipboard]

在VC6上,这个函数请用qFindChild()代替~~请参阅findChildren() 和qFindChild()

20.找出子类2,请参阅上例
QList<T> QObject::findChildren ( const QString & name = QString() ) const

21.找出子类3,请参阅上例
QList<T> QObject::findChildren ( const QRegExp & regExp ) const

22.判断继承关系,是true,否false
bool QObject::inherits ( const char * className ) const
例子:

CODE:
  QTimer *timer = new QTimer;       // QTimer inherits QObject
  timer->inherits("QTimer");       // returns true
  timer->inherits("QObject");       // returns true
  timer->inherits("QAbstractButton"); // returns false

  // QLayout inherits QObject and QLayoutItem
  QLayout *layout = new QLayout;
  layout->inherits("QObject");     // returns true
  layout->inherits("QLayoutItem");   // returns false
[Copy to clipboard]

请参阅metaObject() 和qobject_cast()

23.安装事件过滤
void QObject::installEventFilter ( QObject * filterObj )
请参阅 removeEventFilter(), eventFilter(), 和event().

24.判断一个类是不是Widget组件
bool QObject::isWidgetType () const

25.删除定时器
void QObject::killTimer ( int id )

26.得到对象元信息
const QMetaObject * QObject::metaObject () const [virtual]

27.移动到某一线程
void QObject::moveToThread ( QThread * targetThread )
请参阅thread()

28.得到父类
QObject * QObject::parent () const
请参阅setParent() 和children()

29.得到属性值
QVariant QObject::property ( const char * name ) const
请参阅setProperty(), QVariant::isValid(), 和metaObject()

30.得到一个信号的连接数
int QObject::receivers ( const char * signal ) const [protected]

31.删除事件监控
void QObject::removeEventFilter ( QObject * obj )
请参阅installEventFilter(), eventFilter(), 和event()

32.得到信号的发送者
QObject * QObject::sender () const [protected]

33.设置父类
void QObject::setParent ( QObject * parent )
请参阅 parent() 和QWidget::setParent().

34.设置属性值
bool QObject::setProperty ( const char * name, const QVariant & value )
请参阅property() and metaObject()

35.开始一个定时器
int QObject::startTimer ( int interval )
失败返回0,注意这个参数依赖操作系统的时间
请参阅timerEvent(), killTimer(), and QTimer::singleShot().

36.得到些类的线程
QThread * QObject::thread () const
请参阅moveToThread().

37.计时器事件
void QObject::timerEvent ( QTimerEvent * event ) [virtual protected]
请参阅startTimer(), killTimer(), event()

38.翻译函数,关于这个函数的更多描述请参阅本网站国际化变成这一栏目
QString QObject::tr ( const char * sourceText, const char * comment ) [static]
请参阅trUtf8(), QApplication::translate(), and Internationalization with Qt.

39.翻译函数2
QString QObject::trUtf8 ( const char * sourceText, const char * comment ) [static]


QObject宏

1.Q_CLASSINFO ( Name, Value ),他设置的东西可以在 QObject::metaObject()中找到
例子

CODE:
  class MyClass : public QObject
  {
    Q_OBJECT
    Q_CLASSINFO("Author", "Pierre Gendron")
    Q_CLASSINFO("URL", "[url]http://www.my-organization.qc.ca[/url]")

  public:
    ...
  };
[Copy to clipboard]


2.Q_ENUMS ( ... )

CODE:
Q_ENUMS(Option AlignmentFlag EditMode TransformationMode)
[Copy to clipboard]

更多请参阅Qt's Property System

3.Q_FLAGS ( ... )

CODE:
Q_FLAGS(Options Alignment)
[Copy to clipboard]

更多请参阅Qt's Property System

4.Q_INTERFACES ( ... )接口生命,一般用于写插件
如

CODE:
  class BasicToolsPlugin : public QObject,
                  public BrushInterface,
                  public ShapeInterface,
                  public FilterInterface
  {
    Q_OBJECT
    Q_INTERFACES(BrushInterface ShapeInterface FilterInterface)

  public:
    ...
  };
[Copy to clipboard]


5.Q_OBJECT,略

6.Q_PROPERTY ( ... )
他用来声明一个类的属性,语法如下

CODE:
  Q_PROPERTY(type name
          READ getFunction
          [WRITE setFunction]
          [RESET resetFunction]
          [DESIGNABLE bool]
          [SCRIPTABLE bool]
          [STORED bool])
[Copy to clipboard]

例子:

CODE:
Q_PROPERTY(QString title READ title WRITE setTitle)
编辑 楼主发表于: 2010-06-30 11:39

civilnet
()
级别: 归原
发帖: 282
注册时间:2009-01-02
最后登录:2010-09-20

 

QObject是Qt类体系的唯一基类,就象MFC中的CObject和Dephi中的TObject,是Qt各种功能的源头活水,因此Qt源码分析的第一节就放在这个QObject上
int size = sizeof(QObject);
QObject的大小是8,除了虚函数表指针需要的4个字节以外,另外的4个字节是:
    QObjectData *d_ptr;
QObject中的数据被封装在QObjectData类中了,为什么要封装数据呢?
原因是Qt中有一个很重要的设计模式就是句柄实体模式,也就是以QObject为基类的类一般都是句柄类,一般只有一个指针指向一个实体类,在实体类中保存全部的数据,而且一般情况下这个指针还是私有的,方便以后修改句柄类的实现细节。
因此,也可以说和句柄类继承关系平行的也有一套实体类派生体系,因此,准确的说,Qt的基类其实有两个,一个是QObject,这是句柄类的唯一基类,另一个是QObjectData,这是实体类的基类

QObjectData类定义如下:
class QObjectData {
public:
    virtual ~QObjectData() = 0;
    QObject *q_ptr;
    QObject *parent;
    QObjectList children;

    uint isWidget : 1;
    uint pendTimer : 1;
    uint blockSig : 1;
    uint wasDeleted : 1;
    uint ownObjectName : 1;
    uint sendChildEvents : 1;
    uint receiveChildEvents : 1;
    uint unused : 25;
    int postedEvents;
#ifdef QT3_SUPPORT
    int postedChildInsertedEvents;
#else
    int reserved;
#endif
};
QObject *q_ptr;
这个指针指向实体类对应的句柄类,这和上面的代码
QObjectData *d_ptr;
遥相呼应,使得句柄类和实体类可以双向的引用,为什么是这样的命名方式呢?可能q指的是Qt接口类,d指的是Data数据类,这当然是猜测了,但是或许可以方便你记忆,在Qt中,这两个指针名字是非常重要的,必须记住。
但是仅仅如此还是不容易使用这两个指针,因为它们都是基类的类型,难道每次使用都要类型转换吗?为了简单起见,Qt在这里声明了两个宏

#define Q_DECLARE_PRIVATE(Class) /
    inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(d_ptr); } /
    inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(d_ptr); } /
    friend class Class##Private;

#define Q_DECLARE_PUBLIC(Class) /
    inline Class* q_func() { return static_cast<Class *>(q_ptr); } /
    inline const Class* q_func() const { return static_cast<const Class *>(q_ptr); } /
    friend class Class;
只要在类的头文件中使用这两个宏,就可以通过函数直接得到实体类和句柄类的实际类型了,而且这里还声明了友元,使得数据类和句柄类连访问权限也不用顾忌了。

而且为了cpp文件中调用的方便,更是直接声明了以下两个宏
#define Q_D(Class) Class##Private * const d = d_func()
#define Q_Q(Class) Class * const q = q_func()
好了,使用起来倒是方便了,但是以后局部变量可千万不能声明为d和q了(d,q分别代表了只想实体类对象和句柄类对象的常指针)

这里的d_func和q_func函数是非常常用的函数,可以理解为一个是得到数据类,一个是得到Qt接口类

QObject *parent;
这里指向QObject的父类
QObjectList children;
这里指向QObject相关的子类列表
这确实是个大胆的设计,如果系统中产生了1000000个QObject实例(对于大的系统,这个数字很容易达到吧),每个QObject子类平均下来是100(这个数字可能大了),
光这些指针的开销就有1000000*100*4=400M,是够恐怖的,如果我们必须在灵活性和运行开销之间做一个选择的话,无疑Qt选择了前者,对此我也很难评论其中的优劣,
还是祈求越来越强的硬件水平和Qt这么多年来得到的赫赫威名保佑我们根本就没有这个问题吧,呵呵
总之,Qt确实在内存中保存了所有类实例的树型结构

    uint isWidget : 1;
    uint pendTimer : 1;
    uint blockSig : 1;
    uint wasDeleted : 1;
    uint ownObjectName : 1;
    uint sendChildEvents : 1;
    uint receiveChildEvents : 1;
    uint unused : 25;
这些代码就简单了,主要是一些标记位,为了节省内存开销,这里采用了位域的语法,还保留了25位为unused,留做以后的扩充
#ifdef QT3_SUPPORT
    int postedChildInsertedEvents;
#else
    int reserved;
#endif
这里或许是为了兼容Qt3下序列化的数据吧,即使没有定义QT3_SUPPORT,还是保留了一个数据reserved,以保证整个QObjectData的大小不变

具体看一个例子吧,对这种句柄实体模式加深认识,这就是Qt中的按钮类QPushButton
QPushButton的句柄类派生关系是:
QObject
QWidget
QAbstractButton
   QPushButton
  
QPushButton的实体类派生关系是:
QObjectData
QObjectPrivate
QWidgetPrivate
   QAbstractButtonPrivate
    QPushButtonPrivate

可以看出,这里确实是一个平行体系,只不过实体类派生关系中多了一个QObjectPrivate,这个类封装了线程处理,信号和槽机制等具体的实现,可以说它才是Qt实体类中真正起作用的基类,而QObjectData不过是一层浅浅的数据封装而已。

先不忙了解QObjectPrivate类中的接口和实现,我们先看看在Qt中,句柄类和实体类这两条体系是如何构造的?
QPushButton* quit = new QPushButton("Quit");
创建一个Qt的按钮,简简单单一行代码,其实背后大有玄机
QPushButton::QPushButton(const QString &text, QWidget *parent)
    : QAbstractButton(*new QPushButtonPrivate, parent)
首先QPushButton的构造函数中调用了QAbstractButton的构造函数,同时马上new出来一个QPushButtonPrivate实体类,然后把指针转换为引用传递给QAbstractButton

QAbstractButton::QAbstractButton(QAbstractButtonPrivate &dd, QWidget *parent)
    : QWidget(dd, parent, 0)
QAbstractButton的构造函数中继续调用基类QWidget的构造函数,同时把QPushButtonPrivate实体类指针继续传给基类

QWidget::QWidget(QWidgetPrivate &dd, QWidget* parent, Qt::WFlags f)
    : QObject(dd, ((parent && (parent->windowType() == Qt::Desktop)) ? 0 : parent)), QPaintDevice()
QWidget继续坐着同样的事情

QObject::QObject(QObjectPrivate &dd, QObject *parent)
    : d_ptr(&dd)
终于到了基类QObject,这里就直接把QPushButtonPrivate的指针赋值给了d_ptr(还记得这个变量名称吧)

最终在QPushButton构造时同时产生的new QPushButtonPrivate被写到了QObject中的d_ptr中

QObject::QObject(QObjectPrivate &dd, QObject *parent)
    : d_ptr(&dd)
{
    Q_D(QObject);
    ::qt_addObject(d_ptr->q_ptr = this);
    QThread *currentThread = QThread::currentThread();
    d->thread = currentThread ? QThreadData::get(currentThread)->id : -1;
    Q_ASSERT_X(!parent || parent->d_func()->thread == d->thread, "QObject::QObject()",
               "Cannot create children for a parent that is in a different thread.");
    if (parent && parent->d_func()->thread != d->thread)
        parent = 0;
    if (d->isWidget) {
        if (parent) {
            d->parent = parent;
            d->parent->d_func()->children.append(this);
        }
        // no events sent here, this is done at the end of the QWidget constructor
    } else {
        setParent(parent);
    }
}
然后执行QObject的构造函数,这里主要是一些线程的处理,先不理它

QWidget::QWidget(QWidgetPrivate &dd, QWidget* parent, Qt::WFlags f)
    : QObject(dd, ((parent && (parent->windowType() == Qt::Desktop)) ? 0 : parent)), QPaintDevice()
{
    d_func()->init((parent && parent->windowType() == Qt::Desktop ? parent : 0), f);
}
然后是QWidget的构造函数,这里调用了数据类QWidgetPrivate的init函数,这个函数不是虚函数,因此静态解析成QWidgetPrivate的init函数调用

QAbstractButton::QAbstractButton(QAbstractButtonPrivate &dd, QWidget *parent)
    : QWidget(dd, parent, 0)
{
    Q_D(QAbstractButton);
    d->init();
}
然后是QAbstractButton的构造函数,这里调用了数据类QAbstractButton的init函数,这个函数不是虚函数,因此静态解析成QAbstractButton的init函数调用

QPushButton::QPushButton(const QString &text, QWidget *parent)
    : QAbstractButton(*new QPushButtonPrivate, parent)
{
    Q_D(QPushButton);
    d->init();
    setText(text);
}
然后是QPushButton的构造函数,这里调用了数据类QPushButton的init函数,这个函数不是虚函数,因此静态解析成QPushButton的init函数调用

现在的事情很清楚了,总结一下:
QPushButton在构造的时候同时生成了QPushButtonPrivate指针,QPushButtonPrivate创建时依次调用数据类基类的构造函数
QPushButton的构造函数中显示的调用了基类的构造函数并把QPushButtonPrivate指针传递过去,QPushButton创建时依次调用接口类基类的构造函数
在接口类的构造函数中调用了平行数据类的init函数,因为这个函数不是虚函数,因此就就是此次调用了数据类的init函数

需要指出的是,为什么QPushButtonPrivate实体类指针要转换为引用呢?为什么不是直接传递指针?结论是人家喜欢这样写,就是不传指针传引用,而且要用一个*new之类的怪异语法,
真叫人没有办法,其实这里用指针是一样的,代码看起来也自然一些.

delete quit;
说完了构造,再说说析构

QPushButton::~QPushButton()
{
}
这里当然会调用QPushButton的析构函数了

QAbstractButton::~QAbstractButton()
{
#ifndef QT_NO_BUTTONGROUP
    Q_D(QAbstractButton);
    if (d->group)
        d->group->removeButton(this);
#endif
}
然后是QAbstractButton的析构函数

QWidget::~QWidget()
{
    Q_D(QWidget);
...
}
然后是QWidget的析构函数,这里洋洋洒洒一大堆代码,先不管它

QObject::~QObject()
{
...
}
最后是QObject的析构函数,这里也是洋洋洒洒的一大堆
    Q_D(QObject);
    if (d->wasDeleted) {
#if defined(QT_DEBUG)
        qWarning("Double QObject deletion detected");
#endif
        return;
    }
    d->wasDeleted = true;
这些没有什么好说的,就是设一个wasDeleted的标志,防止再被引用,对于单线程情况下,马上就要被删除了,还搞什么标记啊,根本没用,但是对于多线程情况下,这个标记应该是有用的

    // set all QPointers for this object to zero
    GuardHash *hash = ::guardHash();
    if (hash) {
        QWriteLocker locker(guardHashLock());
        GuardHash::iterator it = hash->find(this);
        const GuardHash::iterator end = hash->end();
        while (it.key() == this && it != end) {
            *it.value() = 0;
            it = hash->erase(it);
        }
    }
这里是支持QPointers的实现代码,我们以后再说

    emit destroyed(this);
Qt的一个指针删除时要发送destroyed信号,一般情况下是没有槽来响应的

    QConnectionList *list = ::connectionList();
    if (list) {
        QWriteLocker locker(&list->lock);
        list->remove(this);
    }
这里清除了信号槽机制中的记录

    if (d->pendTimer) {
        // have pending timers
        QThread *thr = thread();
        if (thr || d->thread == 0) {
            // don't unregister timers in the wrong thread
            QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(thr);
            if (eventDispatcher)
                eventDispatcher->unregisterTimers(this);
        }
    }
这里清除定时器

    d->eventFilters.clear();
这里清除事件过滤机制

    // delete children objects
    if (!d->children.isEmpty()) {
        qDeleteAll(d->children);
        d->children.clear();
    }
这里清除所有子类指针,当然每个子类指针清除时又会清除它的所有子类,因此Qt中new出来的指针很少有显示对应的delete,因为只要最上面的指针被框架删除了,
它所连带的所有子类都被自动删除了

    {
        QWriteLocker locker(QObjectPrivate::readWriteLock());
        ::qt_removeObject(this);

        /*
          theoretically, we cannot check d->postedEvents without
          holding the postEventList.mutex for the object's thread,
          but since we hold the QObjectPrivate::readWriteLock(),
          nothing can go into QCoreApplication::postEvent(), which
          effectively means noone can post new events, which is what
          we are trying to prevent. this means we can safely check
          d->postedEvents, since we are fairly sure it will not
          change (it could, but only by decreasing, i.e. removing
          posted events from a differebnt thread)
        */
        if (d->postedEvents > 0)
            QCoreApplication::removePostedEvents(this);
    }

    if (d->parent)        // remove it from parent object
        d->setParent_helper(0);

    delete d;
    d_ptr = 0;
这里要删除相关的数据类指针了
Qt入门教程【QObject篇】QObject类 QObject类 阅读详情

相关推荐

【Qt中文手册】QObject

Qt几乎所有的类都是从QObject直接或间接继承的,但是你真的了解QObject吗?下面先看看QObject在官方手册中的介绍。 一、QObject简介 1、信号和槽 QObject是所有Qt类的基类,是Qt对象模型的核心。该模型的核心功能是信号和槽的通信机制(有吐槽Qt信号和槽的,个人建议不要用Qt,因为这是它的核心功能)。 创建信号和槽的连接:connect() 销毁连接:disconnec...

郭老二 1万+

QObject类介绍

作为所有Qt类的基类,QObject提供了信号槽机制、对象树、动态属性、元对象系统、事件处理机制、线程安全、国际化等许多重要特性,这些特性可以帮助开发者轻松实现模块间通信、组件化、程序设计以及事件处理等方面的功能。在Qt框架下编程,不管用不用到Qt的特性,都推荐自定义类继承QObject类,这样在需要的时候,就可以随时使用Qt基于QObject类提供的各种特性和机制,而且可以让自定义的类很好地融入到Qt的框架之中。QObject用得好,可以做很多需要运行时动态处理的工作,大大地提高程序的灵活性。

zw_ggr_2017的博客 3593

ElasticSearch读写性能调优

深层次理解,虽然是每隔一秒就会将内存中的segment数据刷新到segment file中,但实际上这里并没有直接到磁盘文件,而是先写入到OS Cache中。以refresh_interval为间隔时间,将保存在ES 内存缓存区中的数据 刷新到 os的文件系统缓存中,定期清空es的buffer,生成segment。注意:ES 的默认设置,已经综合考虑了数据可靠性,搜索的实时性,写入速度,一般不要盲目修改。将segment刷新到os cache中,并开放了查询权限,以提升搜索的实时性。

qq_44027353的博客 1811

QObject类详述

QObject类详述QObject类从Qt类继承,是所有Qt对象的基类,Qt类含有全局需要的各种枚举类型、类型的定义。通常情况下,用户不需要关心这个类,因为它是QObject及很少几个类的基类。例如:它定义了枚举类型ButtonState说明了鼠标按钮的状态,它定义了枚举类型WidgetState说明了窗口部件状态等。1、对象树QObject类是所有Qt对象的基类,是Qt对象模型的核心。 通过QO...

fascinateu的博客 2316

保姆级教程:用PROGRAM_FTDI搞定Xilinx FPGA的JTAG调试器(基于FT232/FT2232/FT4232)

本文详细介绍了如何使用FT232/FT2232/FT4232系列芯片通过PROGRAM_FTDI工具配置Xilinx FPGA的JTAG调试器。从芯片选型、驱动安装到固件烧写和Vivado验证,提供了完整的实操指南和避坑要点,帮助开发者低成本实现高效调试。

weixin_29271053的博客 2152

Debian 12 安装nodejs(包括node、npm、npx、yarn、pnpm、cnpm、bun)

【代码】Debian 12 安装nodejs。

mirana的专栏 8004

QObject

QObject

友善啊,朋友的博客 3920

基于simulink构建一个完整的航空航天器姿态控制与导航仿真模型

航空航天器的姿态控制与导航系统是确保飞行器稳定运行和精确执行任务的核心技术。其目标是通过传感器获取飞行器的状态信息,并利用控制器调整飞行器的姿态,使其按照预定轨迹飞行。基于MATLAB/Simulink平台进行航空航天器姿态控制与导航系统的建模与仿真,可以帮助研究者验证算法性能并优化系统的动态响应。本项目旨在构建一个完整的航空航天器姿态控制与导航仿真模型,包括飞行器动力学建模、传感器模块设计、控制器实现以及导航算法仿真,并通过仿真分析其性能。

xiaoheshang_123的博客 272

Qt类 | QObject类详解

所有的 Qt 控件都继承自QObject。Header:qmake:QT += core事件处理QObject提供了事件处理机制,允许对象接收和处理不同类型的事件,如鼠标点击、键盘输入等。QObject对象可以使用用于接收和处理各种事件,可以被子类重写以自定义事件处理。还可以通过installEventFilter()和eventFilter()函数来过滤或拦截其他对象的事件。信号和槽QObject支持 Qt 的信号和槽机制,允许对象之间进行通信。connect()方法用于建立信号和槽之间的连接,而。

zwcslj的博客 2558

基于毫米波生物感知雷达+STM32设计的独居老人居家监护系统(微信小程序)(192)

当前基于STM32设计的独居老人居家监护系统为独居老人提供一种简便、实时的健康监护服务。该系统通过集成多种传感器和功能模块,能够实时监测老人的生理指标、姿态以及室内环境状况,并通过微信小程序远程显示数据,当出现异常情况时及时发出报警提醒。

1万+

23、工业物流中的多智能体路径规划与碰撞处理策略

本文探讨了工业4.0背景下工业物流中的多智能体路径规划(MAPF)与碰撞处理策略。分析了自动导引车(AGV)等移动资源的应用现状,综述了主流路径规划算法如A*、D*Lite、M*等,以及集中式与分布式碰撞检测方法。重点比较了五种碰撞避免策略:路径交叉、优先级、起始时间调整、无交叉路径和速度调整,提出了基于环境条件的策略选择流程,并通过流程图展示了评估、组合、测试与优化的全过程。文章强调应根据订单不确定性、时间约束、优先级和生产组织等因素综合选择或组合策略,以提升物流效率与系统可靠性。

mac99的博客 125

【Qt】QObject详解

00. 目录 文章目录00. 目录01. 概述02. 线程亲和性03. 没有拷贝构造函数或赋值运算符04. 自动连接05. 动态属性06. 国际化07. 属性文档08. 常用成员方法09. 附录 01. 概述 QObject类是所以Qt类的基类,也是Qt对象模型的核心。这个模型中的核心特性就是能让对象键无缝通信的信号和槽的机制。我们可以使用connect()函数将一个信号连接到一个槽上,也可以使用disconnect()删除这个连接。为了防止无休止的的信号通知,还可以使用blockSignals()来临时阻

C/C++软件工程师、嵌入式软件工程师、物联网研发工程师、C/C++讲师、物联网讲师、嵌入式讲师、鸿蒙讲师---欢迎大家一起交流(私信添加博主微信) 7888

基于STM32设计的水质检测系统_333

水质安全对生态环境、农业生产、工业制造以及人类健康至关重要。针对传统水质检测方式检测周期长、成本高、实时性差的问题,本项目设计并实现了一种基于STM32的水质检测系统。系统采用STM32F103RCT6作为主控芯片,集成水温、pH值、电导率和浊度等传感器,能够实时采集水质数据,并通过OLED显示屏进行本地显示。同时,利用Air724UG 4G模块通过MQTT协议将数据上传至华为云IoT平台,实现远程监测。用户可通过Qt5开发的Android手机APP和Windows上位机查看水质数据,并接收超限报警提示。此

713

QObject QT所有类的基类

QObject是QT所有类的基类,QObject是Qt Object Model的核心CODE:/*什么是Qt Object Model,主要包括如下的东西1.信号和槽2.良好的对象属性,如可查询和很好看,,,~~  3.有力的事件和事件过滤器4.国际化字符设计5.定时器为GUI的事件提供毫秒级的支持6.很优秀的对象树结构7.当对象销毁时指针自动设置为0  8.a dynamic cast

2649

搭建 Newman + Postman + Git + Jenkins 环境教程

一步步搭建 Newman、Postman、Git 和 Jenkins 的环境。这些工具常用来做 API 测试和 CI/CD 自动化,尤其是 Postman 和 Newman 搭配 Git 和 Jenkins,能实现 API 集合的版本管理和自动测试。

Criss@陈磊 435

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

QObject是QT所有类的基类

QObject是QT所有类的基类,QObject是Qt Object Model的核心 CODE: /* 什么是Qt Object Model,主要包括如下的东西 1.信号和槽 2.良好的对象属性,如可查询和很好看,,,~~   3.有力的事件和事件过滤器 4.国际化字符设计 5.定时器为GUI的事件提供毫秒级的支持 6.很优秀的对象树结构 7.当对象销毁时指针自动设置

imxiangzi的专栏 4097

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

QObject是QT所有类的基类,QObject是Qt Object Model的核心

QObject是QT所有类的基类,QObject是Qt Object Model的核心 CODE: /* 什么是Qt Object Model,主要包括如下的东西 1.信号和槽 2.良好的对象属性,如可查询和很好看,,,~~ 3.有力的事件和事件过滤器 4.国际化字符设计 5.定时器为GUI的事件提供毫秒级的支持 6.很优秀的对象树结构 7.当对象销毁时指针自动设置为0

Mittens 的专栏 1630

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

qt多继承限制

qt不支持一个类派生自两个基类为qobject的类。

菜鸟进化史 5295

QT中组件 控件类的关系_qt中类和module的对应关系

一、常见类继承关系二、窗口类继承关系。

2401_87556757的博客 383

QObject基类是什么

是 Qt 框架的核心基类,提供了信号与槽、对象树、事件处理、元对象系统、国际化等核心功能。信号与槽是 Qt 的核心特性之一,用于实现对象之间的通信。通过信号与槽,对象可以在不直接调用对方方法的情况下进行交互,从而实现低耦合和高灵活性。通过将对象设置为其他对象的子对象,可以实现自动内存管理。提供了 Qt 框架中许多核心功能的基础支持,例如信号与槽机制、对象树管理、事件处理以及国际化支持等。(元对象编译器)工具,它解析类中的信号、槽和属性,并生成相应的元信息。:槽是对象中可以被信号触发的函数。

Yy468545的博客 702

Qt自己添加新类并继承QObject

今天用Qt自己添加新类时发现新类并不继承QObject,鼓捣了一上午终于明白过来。 一开始我是直接右键头文件夹,然后点击添加新文件,然后选C++ class, class name命名为自己的,Base class一开始也用的自己的,其实这样就不会让类...

a200332的博客 2383

qt——QObject 与 QWidget 的区别

QObject是QT中所有类的基类,QWidget是所有UI Widget类的基类,所以QObject是QWidget的基类,从QWidget继承也就表示继承了QObject的所有属性。 转载于:https://www.cnblogs.com/tony-li/p/4104400.html...

weixin_30516243的博客 2136

Qt中QObject类的核心作用与使用

QObject是Qt框架的核心基类,提供对象树管理、信号槽机制和元对象系统三大核心功能。对象树管理通过父子关系自动处理内存释放;信号槽机制实现对象间通信;元对象系统支持运行时类型信息和动态属性。QObject还包含对象名称管理、事件处理、生命周期控制等实用功能,并支持自定义属性和工厂模式等高级应用。掌握QObject是深入理解Qt编程的基础,其特性为Qt应用程序开发提供了强大的对象管理和通信能力。

编程与实战的博客 1092

Qt系列文章之(三)— QObject模块 01

Qt系列文章之(三)— QObject模块 01QObject模块介绍以QObject为基类创建用户类实例化并测试对象方法 Qt并不是一定要用来做界面开发,其实Qt内部的很多非界面模块也十分优秀,本文从Qt的第一个基类开始介绍如何认识QObject和据此开发自己的用户类。 QObject模块介绍 QObject的帮助文档第一句这样写“The QObject class is the base class of all Qt objects.” QObject模块是所有Qt核心类(不论是界面类/非界面类)的基

一枚半路出家的码农儿 904
上一篇: S3C2440上MMC/SD卡驱动实例开发讲解(二)
下一篇: 解读QT信号与槽机制里 QMetaObject::connectSlotsByName(QObject *o)的源码
control_tech
博客等级 码龄17年 53粉丝 32原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值