1.void move(int x, int y);
inline void QWidget::move(int ax, int ay)
{ move(QPoint(ax, ay)); }
void QWidget::move(const QPoint &p)
{
Q_D(QWidget);
setAttribute(Qt::WA_Moved);
if (testAttribute(Qt::WA_WState_Created)) {
if (isWindow())
d->topData()->posIncludesFrame = false;
d->setGeometry_sys(p.x() + geometry().x() - QWidget::x(),
p.y() + geometry().y() - QWidget::y(),
width(), height(), true);
d->setDirtyOpaqueRegion();
} else {
// no frame yet: see also QWidgetPrivate::fixPosIncludesFrame(), QWindowPrivate::PositionPolicy.
if (isWindow())
d->topData()->posIncludesFrame = true;
data->crect.moveTopLeft(p); // no frame yet
setAttribute(Qt::WA_PendingMoveEvent);
}
if (d->extra && d->extra->hasWindowContainer)
QWindowContainer::parentWasMoved(this);
}
void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
{
Q_Q(QWidget);
if (extra) { // any size restrictions?
w = qMin(w,extra->maxw);
h = qMin(h,extra->maxh);
w = qMax(w,extra->minw);
h = qMax(h,extra->minh);
}
if (q->isWindow() && q->windowHandle()) {
QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration();
if (!integration->hasCapability(QPlatformIntegration::NonFullScreenWindows)) {
x = 0;
y = 0;
w = q->windowHandle()->width();
h = q->windowHandle()->height();
}
}
QPoint oldp = q->geometry().topLeft();
QSize olds = q->size();
QRect r(x, y, w, h);
bool isResize = olds != r.size();
if (!isMove)
isMove = oldp != r.topLeft();
// We only care about stuff that changes the geometry, or may
// cause the window manager to change its state
if (r.size() == olds && oldp == r.topLeft())
return;
if (!data.in_set_window_state) {
q->data->window_state &= ~Qt::WindowMaximized;
q->data->window_state &= ~Qt::WindowFullScreen;
if (q->isWindow())
topData()->normalGeometry = QRect(0, 0, -1, -1);
}
QPoint oldPos = q->pos();
data.crect = r;
bool needsShow = false;
if (q->isWindow() || q->windowHandle()) {
if (!(data.window_state & Qt::WindowFullScreen) && (w == 0 || h == 0)) {
q->setAttribute(Qt::WA_OutsideWSRange, true);
if (q->isVisible())
hide_sys();
data.crect = QRect(x, y, w, h);
} else if (q->testAttribute(Qt::WA_OutsideWSRange)) {
q->setAttribute(Qt::WA_OutsideWSRange, false);
needsShow = true;
}
}
if (q->isVisible()) {
if (!q->testAttribute(Qt::WA_DontShowOnScreen) && !q->testAttribute(Qt::WA_OutsideWSRange)) {
if (QWindow *win = q->windowHandle()) {
if (q->isWindow()) {
if (isResize && !isMove)
win->resize(w, h);
else if (isMove && !isResize)
win->setPosition(x, y);
else
win->setGeometry(q->geometry());
} else {
QPoint posInNativeParent = q->mapTo(q->nativeParentWidget(),QPoint());
win->setGeometry(QRect(posInNativeParent,r.size()));
}
if (needsShow)
show_sys();
}
if (!q->isWindow()) {
if (renderToTexture) {
QRegion updateRegion(q->geometry());
updateRegion += QRect(oldPos, olds);
q->parentWidget()->d_func()->invalidateBackingStore(updateRegion);
} else if (isMove && !isResize) {
moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y());
} else {
invalidateBackingStore_resizeHelper(oldPos, olds);
}
}
}
if (isMove) {
QMoveEvent e(q->pos(), oldPos);
QCoreApplication::sendEvent(q, &e);
}
if (isResize) {
QResizeEvent e(r.size(), olds);
QCoreApplication::sendEvent(q, &e);
if (q->windowHandle())
q->update();
}
} else { // not visible
if (isMove && q->pos() != oldPos)
q->setAttribute(Qt::WA_PendingMoveEvent, true);
if (isResize)
q->setAttribute(Qt::WA_PendingResizeEvent, true);
}
}
setGeometry_sys函数设置移动的目的坐标, 最后一个参数设置为true表示为移动操作。
2.void resize(int w, int h);
inline void QWidget::resize(int w, int h)
{ resize(QSize(w, h)); }
void QWidget::resize(const QSize &s)
{
Q_D(QWidget);
setAttribute(Qt::WA_Resized);
if (testAttribute(Qt::WA_WState_Created)) {
d->fixPosIncludesFrame();
d->setGeometry_sys(geometry().x(), geometry().y(), s.width(), s.height(), false);
d->setDirtyOpaqueRegion();
} else {
const auto oldRect = data->crect;
data->crect.setSize(s.boundedTo(maximumSize()).expandedTo(minimumSize()));
if (oldRect != data->crect)
setAttribute(Qt::WA_PendingResizeEvent);
}
}
3.virtual QSize sizeHint() const;
/*!
\property QWidget::sizeHint
\brief the recommended size for the widget
If the value of this property is an invalid size, no size is
recommended.
The default implementation of sizeHint() returns an invalid size
if there is no layout for this widget, and returns the layout's
preferred size otherwise.
\sa QSize::isValid(), minimumSizeHint(), sizePolicy(),
setMinimumSize(), updateGeometry()
*/
QSize QWidget::sizeHint() const
{
Q_D(const QWidget);
if (d->layout)
return d->layout->totalSizeHint();
return QSize(-1, -1);
}
/*!
\internal
Also takes contentsMargins and menu bar into account.
*/
QSize QLayout::totalSizeHint() const
{
Q_D(const QLayout);
int side=0, top=0;
if (d->topLevel) {
QWidget *pw = parentWidget();
pw->ensurePolished();
QWidgetPrivate *wd = pw->d_func();
side += wd->leftmargin + wd->rightmargin;
top += wd->topmargin + wd->bottommargin;
}
QSize s = sizeHint();
if (hasHeightForWidth())
s.setHeight(heightForWidth(s.width() + side));
#if QT_CONFIG(menubar)
top += menuBarHeightForWidth(d->menubar, s.width());
#endif
return s + QSize(side, top);
}
如果是layout, 返回totalSizeHint(), 计算时考虑了边界和菜单栏大小;否则,返回无效的size.
4.void updateGeometry();
/*!
Notifies the layout system that this widget has changed and may
need to change geometry.
Call this function if the sizeHint() or sizePolicy() have changed.
For explicitly hidden widgets, updateGeometry() is a no-op. The
layout system will be notified as soon as the widget is shown.
*/
void QWidget::updateGeometry()
{
Q_D(QWidget);
d->updateGeometry_helper(false);
}
void QWidgetPrivate::updateGeometry_helper(bool forceUpdate)
{
Q_Q(QWidget);
if (widgetItem)
widgetItem->invalidateSizeCache();
QWidget *parent;
if (forceUpdate || !extra || extra->minw != extra->maxw || extra->minh != extra->maxh) {
const int isHidden = q->isHidden() && !size_policy.retainSizeWhenHidden() && !retainSizeWhenHiddenChanged;
if (!q->isWindow() && !isHidden && (parent = q->parentWidget())) {
if (parent->d_func()->layout)
parent->d_func()->layout->invalidate();
else if (parent->isVisible())
QCoreApplication::postEvent(parent, new QEvent(QEvent::LayoutRequest));
}
}
}
通知布局系统此Widget已更改并且可能需要更改Geometry。
5.void adjustSize();
void QWidget::adjustSize()
{
Q_D(QWidget);
ensurePolished();
QSize s = d->adjustedSize();
if (d->layout)
d->layout->activate();
if (s.isValid())
resize(s);
}
调用了resize()函数改变尺寸。
6.QPoint mapFromGlobal(const QPoint &) const;
QPoint QWidget::mapFromGlobal(const QPoint &pos) const
{
return mapFromGlobal(QPointF(pos)).toPoint();
}
/*!
\fn QPointF QWidget::mapFromGlobal(const QPointF &pos) const
Translates the global screen coordinate \a pos to widget
coordinates.
\sa mapToGlobal(), mapFrom(), mapFromParent()
\since 6.0
*/
QPointF QWidget::mapFromGlobal(const QPointF &pos) const
{
const MapToGlobalTransformResult t = mapToGlobalTransform(this);
const QPointF windowLocal = t.window ? t.window->mapFromGlobal(pos) : pos;
return t.transform.inverted().map(windowLocal);
}
QPointF QWindow::mapFromGlobal(const QPointF &pos) const
{
Q_D(const QWindow);
// QTBUG-43252, prefer platform implementation for foreign windows.
if (d->platformWindow
&& (d->platformWindow->isForeignWindow() || d->platformWindow->isEmbedded())) {
return QHighDpi::fromNativeLocalPosition(d->platformWindow->mapFromGlobalF(QHighDpi::toNativeLocalPosition(pos, this)), this);
}
if (!QHighDpiScaling::isActive())
return pos - d->globalPosition();
// Calculate local position in the native coordinate system. (See comment for the
// correspinding mapToGlobal() code above).
QPointF nativeGlobalPos = QHighDpi::toNativeGlobalPosition(pos, this);
QPointF nativeWindowGlobalPos = QHighDpi::toNativeGlobalPosition(QPointF(d->globalPosition()), this);
QPointF nativeLocalPos = nativeGlobalPos - nativeWindowGlobalPos;
QPointF deviceIndependentLocalPos = QHighDpi::fromNativeLocalPosition(nativeLocalPos, this);
return deviceIndependentLocalPos;
}
7.QPoint mapToGlobal(const QPoint &) const;
QPoint QWidget::mapToGlobal(const QPoint &pos) const
{
return mapToGlobal(QPointF(pos)).toPoint();
}
/*!
\fn QPointF QWidget::mapToGlobal(const QPointF &pos) const
Translates the widget coordinate \a pos to global screen
coordinates. For example, \c{mapToGlobal(QPointF(0,0))} would give
the global coordinates of the top-left pixel of the widget.
\sa mapFromGlobal(), mapTo(), mapToParent()
\since 6.0
*/
QPointF QWidget::mapToGlobal(const QPointF &pos) const
{
const MapToGlobalTransformResult t = mapToGlobalTransform(this);
const QPointF g = t.transform.map(pos);
return t.window ? t.window->mapToGlobal(g) : g;
}
static MapToGlobalTransformResult mapToGlobalTransform(const QWidget *w)
{
MapToGlobalTransformResult result;
result.window = nullptr;
for ( ; w ; w = w->parentWidget()) {
#if QT_CONFIG(graphicsview)
if (QGraphicsProxyWidget *qgpw = graphicsProxyWidget(w)) {
if (const QGraphicsScene *scene = qgpw->scene()) {
const QList <QGraphicsView *> views = scene->views();
if (!views.isEmpty()) {
result.transform *= qgpw->sceneTransform();
result.transform *= views.first()->viewportTransform();
w = views.first()->viewport();
}
}
}
#endif // QT_CONFIG(graphicsview)
QWindow *window = w->windowHandle();
if (window && canMapPosition(window)) {
result.window = window;
break;
}
const QPoint topLeft = w->geometry().topLeft();
result.transform.translate(topLeft.x(), topLeft.y());
if (w->isWindow())
break;
}
return result;
}
QTransform &QTransform::translate(qreal dx, qreal dy)
{
if (dx == 0 && dy == 0)
return *this;
#ifndef QT_NO_DEBUG
if (qIsNaN(dx) | qIsNaN(dy)) {
nanWarning("translate");
return *this;
}
#endif
switch(inline_type()) {
case TxNone:
m_matrix[2][0] = dx;
m_matrix[2][1] = dy;
break;
case TxTranslate:
m_matrix[2][0] += dx;
m_matrix[2][1] += dy;
break;
case TxScale:
m_matrix[2][0] += dx * m_matrix[0][0];
m_matrix[2][1] += dy * m_matrix[1][1];
break;
case TxProject:
m_matrix[2][2] += dx * m_matrix[0][2] + dy * m_matrix[1][2];
Q_FALLTHROUGH();
case TxShear:
case TxRotate:
m_matrix[2][0] += dx * m_matrix[0][0] + dy * m_matrix[1][0];
m_matrix[2][1] += dy * m_matrix[1][1] + dx * m_matrix[0][1];
break;
}
if (m_dirty < TxTranslate)
m_dirty = TxTranslate;
return *this;
}
8.void setFixedSize(int w, int h);
/*!
\fn void QWidget::setFixedSize(int w, int h)
\overload
Sets the width of the widget to \a w and the height to \a h.
*/
void QWidget::setFixedSize(int w, int h)
{
Q_D(QWidget);
bool minSizeSet = d->setMinimumSize_helper(w, h);
bool maxSizeSet = d->setMaximumSize_helper(w, h);
if (!minSizeSet && !maxSizeSet)
return;
if (isWindow())
d->setConstraints_sys();
else
d->updateGeometry_helper(true);
if (w != QWIDGETSIZE_MAX || h != QWIDGETSIZE_MAX)
resize(w, h);
}
先检查w和h是否允许设置,然后调用resize()函数设置宽和高。
|