带你一文搞懂Qt Widget的show、hide、close、setVisible、setHidden的作用和区别

QWidget之show、hide、close、setVisible、setHidden

  • 一、 源码分析
    • 1.show
    • 2.hide
    • 3.close
    • 4.setVisible
    • 5.setHidden
  • 二、总结作用和区别

按照常规思维可能一个GUI窗口带有show, hide, delete三个方法应该就可以满足显隐需求,事实Qt的窗口提供了好几个方法,不仔细研究的话真有点眼花缭乱的感觉,不知道到底该调用哪个方法才是对的。本文结合Qt的源码一探究竟。

这几个方法定义qwidget.h头文件中:

public Q_SLOTS:
    // Widget management functions
    virtual void setVisible(bool visible);
    void setHidden(bool hidden);
    void show();
    void hide();
    
    void showMinimized();
    void showMaximized();
    void showFullScreen();
    void showNormal();
    
    bool close();
    void raise();
    void lower();

一、 源码分析

1.show

源码实现:

void QWidget::show()
{
    Qt::WindowState defaultState = QGuiApplicationPrivate::platformIntegration()->defaultWindowState(data->window_flags);
    if (defaultState == Qt::WindowFullScreen)
        showFullScreen();
    else if (defaultState == Qt::WindowMaximized)
        showMaximized();
    else
        setVisible(true); // Don't call showNormal() as not to clobber Qt::Window(Max/Min)imized
}

作用是显示窗口及其子窗口部件。

可以看到源码实现是根据系统平台的 window flag来决定调用行为,

实际上相当于调用了showFullScreen()、showMaximized()或setVisible(true)

2.hide

源码实现:

void QWidget::hide()
{
    setVisible(false);
}

可以看到实际上调用了setVisible,hide相当于setVisible的马甲

3.close

源码实现:

bool QWidgetPrivate::close_helper(CloseMode mode)
{
	//...省略部分
    bool quitOnClose = q->testAttribute(Qt::WA_QuitOnClose);
    if (mode != CloseNoEvent) {
        QCloseEvent e;
        if (mode == CloseWithSpontaneousEvent)
            QApplication::sendSpontaneousEvent(q, &e);
        else
            QCoreApplication::sendEvent(q, &e);
        if (!that.isNull() && !e.isAccepted()) {
            data.is_closing = 0;
            return false;
        }
    }
    if (!that.isNull() && !q->isHidden())
        q->hide();
        
	//...省略部分
    if (!that.isNull()) {
        data.is_closing = 0;
        if (q->testAttribute(Qt::WA_DeleteOnClose)) {
            q->setAttribute(Qt::WA_DeleteOnClose, false);
            q->deleteLater();
        }
    }
    return true;
}
bool QWidget::close()
{
    return d_func()->close_helper(QWidgetPrivate::CloseWithEvent);
}

这里源码比较长,只摘取了部分关键代码,根据分析可以得到close作用:

关闭窗口。如果已关闭,则返回true;否则返回 false。

首先,它向窗口发送一个QCloseEvent。QWidget::closeEvent()的实现接受关闭事件。

然后,就是close里面也调用了hide()函数。

需要注意的是:如果窗口设置了Qt::WA_DeleteClose标志,则close调用后窗口会被删除。

4.setVisible

这个源码实现比较长,这里就不贴源码了,做了很多的操作和判断,大致关键作用就是

@1.设置属性显示或者隐藏属性

setAttribute(Qt::WA_WState_Visible, bool visible);

@2.发送QShowEvent 或者 QHideEvent 事件

QShowEvent showEvent 或者 QHideEvent hideEvent;

QCoreApplication::sendEvent(q, &showEvent);

@3.调用了QWidgetWindow的函数执行native窗口的显示或隐藏

window->setNativeWindowVisibility(bool);

当然此函数还处理了focus焦点相关, 子控件的显示和隐藏操作

5.setHidden

void QWidget::setHidden(bool hidden)
{
    setVisible(!hidden);
}

此函数是setVisible的马甲,里面直接调用setVisible。

二、总结作用和区别

显示:show、setVisible(true)、setHidden(false)

隐藏:hide、close、setHidden(true)、setVisible(true)

当设置了 setAttribute(Qt::WA_DeleteClose);属性时, 调用close会将窗口销毁。

区别:setVisible是更底一层的接口,基本其他几个方法都有调用这个接口。

其中hide、setHidden可视为setVisible的完全马甲,是直接调用此函数的实现。

当要销毁窗口时除了setAttribute(Qt::WA_DeleteClose), close的配合,也可通过调用 delete widget 或者widget->deleteLater() 这样来实现销毁。

作者:费码程序猿

欢迎技术交流:QQ:255895056

转载请注明出处,如有不当欢迎指正

本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://www.net2asp.com/f7d5a54563.html