# 2024.04.21

```cpp
template <typename T>
void QWidgetPrivate::update(T r)
{
    Q_Q(QWidget);

    if (!q->isVisible() || !q->updatesEnabled())
        return;

    T clipped = r & q->rect();

    if (clipped.isEmpty())
        return;

    if (q->testAttribute(Qt::WA_WState_InPaintEvent)) {
        QApplication::postEvent(q, new QUpdateLaterEvent(clipped));
        return;
    }

    QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
    if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore)
        tlwExtra->backingStoreTracker->markDirty(clipped, q);
}
```

其中Q\_Q是一个宏，其定义位于qglobal.h文件

```cpp
#define Q_Q(Class) Class * const q = q_func()
```

所以 q 是一个指向QWidget的指针（关键问题在于是怎么指回去的）

```cpp
q->testAttribute(Qt::WA_WState_InPaintEvent)

inline bool QWidget::testAttribute(Qt::WidgetAttribute attribute) const
{
    if (attribute < int(8*sizeof(uint)))
        return data->widget_attributes & (1<<attribute);
    return testAttribute_helper(attribute);
}
```

q\_func()又是何方神圣呢？在qwidget\_p.h中，

```cpp
class Q_WIDGETS_EXPORT QWidgetPrivate : public QObjectPrivate
{
    Q_DECLARE_PUBLIC(QWidget)
}
```

其中Q\_DECLARE\_PUBLIC是一个宏，其定义位于qglobal.h文件

```cpp
#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;
```

再看q\_ptr是什么，

QWidgetPrivate继承自QObjectPrivate，QObjectPrivate继承自QObjectdata


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://tysun.gitbook.io/c++/2024.04.21.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
