Qt布局系统提供了一种简单而强大的方式来自动排列小部件内的子小部件,以确保它们充分利用可用空间。 Qt跨平台的C图形用户界面库,最新版免费下载,在线文档,视频教程,Qt正版购买慧都网手动布局 如果您正在制作独一无二的特殊布局,还可以制作如前几篇文章所述的自定义小部件,重新实现QWidget::resizeEvent()来计算所需的尺寸分布并在每个子集上调用setGeometry()。 当需要重新计算布局时,小部件将获得QEvent::LayoutRequest类型的事件,重新实现QWidget::event()来处理QEvent::LayoutRequest事件。如何编写自定义布局管理器 手动布局的替代方法是通过继承QLayout来编写自己的布局管理器,边框布局和流布局示例展示了如何执行此操作。 这里我们详细介绍一个例子。CardLayout类的灵感来自同名的Java布局管理器,它将项目(小部件或嵌套布局)放在彼此的顶部,每个项目由QLayout::spacing()偏移。 要编写自己的布局类,您必须定义以下内容:存储布局处理的项目的数据结构,每个项目都是一个QLayoutItem,我们将在本例中使用QList。addItem(),如何将项目添加到布局。setGeometry(),如何执行布局。sizeHint(),布局的首选大小。itemAt(),如何迭代布局。takeAt(),如何从布局中删除项目。 在大多数情况下,您还将实现minimumSize()。 HeaderFile(card。h)ifndefCARDHdefineCARDHincludeQtWidgetsincludeQListclassCardLayout:publicQLayout{public:CardLayout(intspacing):QLayout(){setSpacing(spacing);}CardLayout(intspacing,QWidgetparent):QLayout(parent){setSpacing(spacing);}CardLayout();voidaddItem(QLayoutItemitem)override;QSizesizeHint()constoverride;QSizeminimumSize()constoverride;intcount()constoverride;QLayoutItemitemAt(int)constoverride;QLayoutItemtakeAt(int)override;voidsetGeometry(constQRectrect)override;private:QListQLayoutItemmitems;};endif ImplementationFile(card。cpp)includecard。h 首先我们定义count()来获取列表中的项目数。intCardLayout::count()const{QList::size()returnsthenumberofQLayoutItemsinmitemsreturnmitems。size();} 然后我们定义了两个遍历布局的函数:itemAt()和takeAt()。布局系统内部使用这些函数来处理小部件的删除,它们也可供应用程序程序员使用。 itemAt()返回给定索引处的项目,takeAt()删除给定索引处的项目,并将其返回。在这种情况下,我们使用列表索引作为布局索引。在我们有更复杂的数据结构的其他情况下,可能需要花费更多的精力来定义项目的线性顺序。QLayoutItemCardLayout::itemAt(intidx)const{QList::value()performsindexchecking,andreturnsnullptrifweareoutsidethevalidrangereturnmitems。value(idx);}QLayoutItemCardLayout::takeAt(intidx){QList::takedoesnotdoindexcheckingreturnidx0idxmitems。size()?mitems。takeAt(idx):0;} addItem()实现布局项的默认放置策略,必须实现此功能。它由QLayout::add()使用,由将布局作为父级的QLayout构造函数使用。如果您的布局具有需要参数的高级放置选项,则必须提供额外的访问函数,例如QGridLayout::addItem()、QGridLayout::addWidget()和QGridLayout::addLayout()的跨行和跨列重载。voidCardLayout::addItem(QLayoutItemitem){mitems。append(item);} 布局接管添加的项目的责任,由于QLayoutItem不继承QObject,我们必须手动删除项目。在析构函数中,使用takeAt()从列表中删除每个项目,然后将其删除。CardLayout::CardLayout(){QLayoutItemitem;while((itemtakeAt(0)))deleteitem;} setGeometry()函数实际上执行布局,作为参数提供的矩形不包括margin()。如果相关,请使用spacing()作为项目之间的距离。voidCardLayout::setGeometry(constQRectr){QLayout::setGeometry(r);if(mitems。size()0)return;intwr。width()(mitems。count()1)spacing();inthr。height()(mitems。count()1)spacing();inti0;while(imitems。size()){QLayoutItemomitems。at(i);QRectgeom(r。x()ispacing(),r。y()ispacing(),w,h);osetGeometry(geom);i;}} sizeHint()和minimumSize()在实现上通常非常相似,两个函数返回的尺寸都应该包括spacing(),但不包括margin()。QSizeCardLayout::sizeHint()const{QSizes(0,0);intnmitems。count();if(n0)sQSize(100,70);startwithanicedefaultsizeinti0;while(in){QLayoutItemomitems。at(i);ss。expandedTo(osizeHint());i;}returnsnQSize(spacing(),spacing());}QSizeCardLayout::minimumSize()const{QSizes(0,0);intnmitems。count();inti0;while(in){QLayoutItemomitems。at(i);ss。expandedTo(ominimumSize());i;}returnsnQSize(spacing(),spacing());}Qt商用组件推荐QtitanRibbonRibbonUI组件:是一款遵循MicrosoftRibbonUIParadigmforQt技术的RibbonUI组件,QtitanRibbon致力于为Windows、Linux和MacOSX提供功能完整的Ribbon组件。QtitanChartQt类图表组件:是一个C库,代表一组控件,这些控件使您可以快速地为应用程序提供漂亮而丰富的图表。QtitanDataGridQt网格组件:提供了一套完整的标准QTableView函数和传统组件无法实现的独特功能。使您能够将不同来源的各类数据加载到一个快速、灵活且功能强大的可编辑网格中,支持排序、分组、报告、创建带状列、拖放按钮和许多其他方便的功能。QtitanNavigation:QtitanNavigationDesignUI组件是一组GUI控件,它实现了菜单、导航框、命令栏等导航界面,并让您以更少的滚动和点击次数有效地查看所有实体(工作区、网格或其他项目)。QtitanDocking:允许您像VisualStudio一样为您的伟大应用程序配备可停靠面板和可停靠工具栏。黑色、白色、蓝色调色板完全支持VisualStudio2019主题!