`

QSizeGrip 小记

 
阅读更多

QSizeGrip 是干嘛用的,Manual中如是说:

  • The QSizeGrip class provides a resize handle for resizing top-level windows.

一般位于顶级窗口(QMainWindow或QDialog)的右下角

  • 它是QWidget的派生类,你可以放置到另一个QWidget的任何位置
  • 通过它可以改变它所在顶级窗口的大小

BUG?

当看到下面这些东西的时候

  • QTBUG-13975: QSizeGrip does not handle ESC or ALT-TAB correctly on Windows

  • QTBUG-13074: QSizeGrip not giving MouseButtonRelease Event on Windows

  • QTBUG-7350: QStatusBar::setSizeGripEnabled ( false ) has no effect on Mac OS X

  • QTBUG-22867: QSizeGrip crashes when reparented

  • ...

突然感觉的到这个看似普通的,而且源码短小的QWidget的派生类,似乎大有看头

源码

  • 源码结构不太复杂,但是里面与平台相关的部分尚不太了解(故尔忽略.

几乎所有的QWidget的派生类都会重新实现

    void paintEvent(QPaintEvent *);

QSizeGrip也不例外。

QSizeGrip主要就是响应鼠标左键动作,故尔,重新实现

    void mousePressEvent(QMouseEvent *);
    void mouseMoveEvent(QMouseEvent *);
    void mouseReleaseEvent(QMouseEvent *mouseEvent);

这部分是重点(先略过吧)

QSizeGrip需要根据其所处的顶级窗口的状态(最大化、全屏等)来决定其是否隐藏,这是通过事件过滤器来实现的。

bool QSizeGrip::eventFilter(QObject *o, QEvent *e)
{
    Q_D(QSizeGrip);
    if ((isHidden() && testAttribute(Qt::WA_WState_ExplicitShowHide))
        || e->type() != QEvent::WindowStateChange
                || o != d->tlw) {
        return QWidget::eventFilter(o, e);
    }
    Qt::WindowStates sizeGripNotVisibleState = Qt::WindowFullScreen;
#ifndef Q_WS_MAC
    sizeGripNotVisibleState |= Qt::WindowMaximized;
#endif
    // Don't show the size grip if the tlw is maximized or in full screen mode.
    setVisible(!(d->tlw->windowState() & sizeGripNotVisibleState));
    setAttribute(Qt::WA_WState_ExplicitShowHide, false);
    return QWidget::eventFilter(o, e);
}

配合这个东西,QSizeGripPrivate 中:

    void updateTopLevelWidget()
    {
        Q_Q(QSizeGrip);
        QWidget *w = qt_sizegrip_topLevelWidget(q);
        if (tlw == w)
            return;
        if (tlw)
            tlw->removeEventFilter(q);
        tlw = w;
        if (tlw)
            tlw->installEventFilter(q);
    }

    // This slot is invoked by QLayout when the size grip is added to
    // a layout or reparented after the tlw is shown. This re-implementation is basically
    // the same as QWidgetPrivate::_q_showIfNotHidden except that it checks
    // for Qt::WindowFullScreen and Qt::WindowMaximized as well.
    void _q_showIfNotHidden()
    {
        Q_Q(QSizeGrip);
        bool showSizeGrip = !(q->isHidden() && q->testAttribute(Qt::WA_WState_ExplicitShowHide));
        updateTopLevelWidget();
        if (tlw && showSizeGrip) {
            Qt::WindowStates sizeGripNotVisibleState = Qt::WindowFullScreen;
#ifndef Q_WS_MAC
            sizeGripNotVisibleState |= Qt::WindowMaximized;
#endif
            // Don't show the size grip if the tlw is maximized or in full screen mode.
            showSizeGrip = !(tlw->windowState() & sizeGripNotVisibleState);
        }
        if (showSizeGrip)
            q->setVisible(true);
    }

此外,QSizeGrip会跟着所在窗口移动,所以

 void moveEvent(QMoveEvent *moveEvent);

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics