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

QWidget之show、hide、close、setVisible、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
转载请注明出处,如有不当欢迎指正

猜你喜欢

转载自blog.csdn.net/haohaohaihuai/article/details/131717692
今日推荐