常用Qt的同学,在编译GUI的应用程序时,肯定都遇到过Z-order的warning,检查ui文件的也没有发现任何的不对。对于像我一样有强迫症的人来说,真是恶心的不行。
今天就把这个问题的来龙去脉给大家讲一讲。带我慢慢道来。
一、创建一个ui文件,如下图所示
窗口组件由两个弹簧、两个QPushButton组成。
应该很多同学都知道.ui文件实际为xml格式的文本文件,那么,我们就打开看一下,内部到底是怎么实现,顺便画画重点。
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>xxTestClass</class>
<widget class="QWidget" name="xxTestClass"> 主窗口
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>600</width>
<height>41</height>
</rect>
</property>
<property name="windowTitle"> 窗口标题
<string>xxTest</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout"> 水平布局
<item>
<spacer name="horizontalSpacer"> 左侧弹簧
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton"> 1按钮
<property name="text">
<string>1</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_2"> 2按钮
<property name="text">
<string>2</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2"> 右侧弹簧
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
<zorder>horizontalSpacer</zorder> Z-order
<zorder>horizontalSpacer_2</zorder>
<zorder>pushButton_2</zorder>
<zorder>pushButton</zorder>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
<include location="xxTest.qrc"/>
</resources>
<connections/>
</ui>
那么,该ui通过uic解析后生成的.h文件又是什么样的呢?(designer中“窗体”>“查看代码”)
/********************************************************************************
** Form generated from reading UI file 'xxTestl11936.ui'
**
** Created by: Qt User Interface Compiler version 5.6.3
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef XXTESTL11936_H
#define XXTESTL11936_H
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QSpacerItem>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_xxTestClass
{
public:
QHBoxLayout *horizontalLayout;
QSpacerItem *horizontalSpacer;
QPushButton *pushButton;
QPushButton *pushButton_2;
QSpacerItem *horizontalSpacer_2;
void setupUi(QWidget *xxTestClass)
{
if (xxTestClass->objectName().isEmpty())
xxTestClass->setObjectName(QStringLiteral("xxTestClass"));
xxTestClass->resize(600, 41);
horizontalLayout = new QHBoxLayout(xxTestClass);
horizontalLayout->setSpacing(6);
horizontalLayout->setContentsMargins(11, 11, 11, 11);
horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout->addItem(horizontalSpacer);
pushButton = new QPushButton(xxTestClass);
pushButton->setObjectName(QStringLiteral("pushButton"));
horizontalLayout->addWidget(pushButton);
pushButton_2 = new QPushButton(xxTestClass);
pushButton_2->setObjectName(QStringLiteral("pushButton_2"));
horizontalLayout->addWidget(pushButton_2);
horizontalSpacer_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout->addItem(horizontalSpacer_2);
// raise()由zorder解析而来
pushButton_2->raise();
pushButton->raise();
retranslateUi(xxTestClass);
QMetaObject::connectSlotsByName(xxTestClass);
} // setupUi
void retranslateUi(QWidget *xxTestClass)
{
xxTestClass->setWindowTitle(QApplication::translate("xxTestClass", "xxTest", Q_NULLPTR));
pushButton->setText(QApplication::translate("xxTestClass", "1", Q_NULLPTR));
pushButton_2->setText(QApplication::translate("xxTestClass", "2", Q_NULLPTR));
} // retranslateUi
};
namespace Ui {
class xxTestClass: public Ui_xxTestClass {};
} // namespace Ui
QT_END_NAMESPACE
#endif // XXTESTL11936_H
// raise()由zorder解析而来
pushButton_2->raise();
pushButton->raise();★★★最后调用raise()的在最顶层
大家有没有发现,在ui文件的xml文件中明明两个弹簧也使用zorder进行了包裹,为什么在生成的.h文件中没有调用raise()?
<zorder>horizontalSpacer</zorder> Z-order
<zorder>horizontalSpacer_2</zorder>
<zorder>pushButton_2</zorder>
<zorder>pushButton</zorder>
要解释上面的原因就需要编译时的warning信息来解释了。
Warning: Z-order assignment: 'horizontalSpacer' is not a valid widget.
horizontalSpacer不是合理的控件,因为QSpacerItem不继承自QWidget
所以,前前后后这个问题都是Qt自己造成的,我认为这个问题可解决,也可以不解决,不会造成程序问题。
说到这,估计大家也大致清楚怎么解决了,那就是文本格式打开.ui文件,删除如下两行
<zorder>horizontalSpacer</zorder>
<zorder>horizontalSpacer_2</zorder>
总结
1、QSpacerItem不是合理的控件,因为QSpacerItem不继承自QWidget
2、这个问题可解决,也可以不解决,不会造成程序问题
3、如果非要解决,ui文件删除使用zorder标签包裹的非控件内容