当前位置:   article > 正文

Qt Widget Z-Order理解_qt zorder

qt zorder

Z-Order

Z-Order指的是三维坐标系中的Z轴顺序,而在系统视图中,X轴和Y轴往往表示平面的宽高方向(可以理解为显示器的宽高),而Z轴表示屏幕到视线的方向,如下图所示:

所以Z轴的坐标会影响人看到的东西,在X和Y坐标一样,且大小一致的两个Item中哪个能被用户看到,取决于Z轴的坐标,Z轴值大的覆盖小的。

QML Z-Order

QML中Item有一个属性z,该属性能够控制Item的Z轴值,具体介绍可以参考官网Item

QWidget Z-Order

QWidget中并没有关于Z-Order的属性,经过一些测试后发现虽然QWidget没有关于Z-Order的属性,但是其通过其他方式实现了。
一开始查找资料的时候只发现以下三个接口:

// 将当前Widget放到父窗口组件堆栈中的w窗口的下面(在视觉效果上就是Widget被w窗口掩盖)
void QWidget::stackUnder(QWidget *w)

// 将当前Widget上升到父窗口组件堆栈的顶部(在视觉效果上会掩盖住同堆栈内的其他Widget)
void QWidget::raise()

// 将当前Widget降低到父窗口组件堆栈的底部(在视觉效果上会被同堆栈内的其他Widget掩盖)
void QWidget::lower()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

从这些接口的注释可以看出child widget在父窗口对象中是用一个堆栈维护的,这里我就联想到QObject对象会维护一个QObjectList,在析构的时候先行析构child object。难道这个QObjectList和Z-Order有关系?那就测试一下吧:
测试方法是两个子窗口通过鼠标双击调用raise()实现以下效果:

看一下主要代码:

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    for (int i = 0; i < 2; i++) {
        widgets[i] = new ChildWidget(this);
        widgets[i]->setText(QString("order%1").arg(i));
        widgets[i]->setObjectName(QString("order%1").arg(i));
        connect(widgets[i], &ChildWidget::sigDBClicked, this, &Widget::onChildDbClicked);
    }
    widgets[0]->setStyleSheet("background: red;");
    widgets[0]->move(10, 10);
    widgets[1]->setStyleSheet("background: black;");
    widgets[1]->move(210, 50);

    qDebug() << "----------";
    for (auto obj : this->children()) {
        qDebug() << obj;
    }
    qDebug() << "----------";
}

// slot
void Widget::onChildDbClicked()
{
    qDebug() << "----------";
    static_cast<ChildWidget*>(sender())->raise();
    for (auto obj : this->children()) {
        qDebug() << obj;
    }
    qDebug() << "----------";
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

通过gif和代码可以看出raise()函数修改的父窗口组件堆栈其实就是父Object的children。那么parent Widget在显示child Widgets时就是通过QObjectList来处理的,先添加的child Widget会被后添加的parent Widget覆盖。

总结

  1. QWidget的视觉Z-Order可以通过stackUnder、lower、raise三个函数来修改
  2. 初始化的Z-Order和添加child Widget的先后有关
本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号