更改 QGridLayout 中单个 QWidget 的间距

Posted

技术标签:

【中文标题】更改 QGridLayout 中单个 QWidget 的间距【英文标题】:Change spacing for individual QWidgets in a QGridLayout 【发布时间】:2016-02-03 16:22:49 【问题描述】:

我正在开发一个允许用户使用 2D 网格放置多米诺骨牌的项目。我使用 QGridLayout 和 QWidgets 制作了一个基本版本,但我意识到我希望多米诺骨牌之间的距离是可变的,并且基于它所面对的方向。

我的问题是,如何更改 QGridLayout 中各个 QWidget 之间的间距?我添加了图片以供参考。 (抱歉画质不好,只能用MS Paint)

【问题讨论】:

如果您想以这种方式单独设置它们的位置,则小部件不能全部位于同一布局中。您需要将它们放入单独的 QHBoxLayouts 中,然后将它们堆叠在 QVBoxLayout 中。 感谢您的回复,但我怀疑这是否可行,因为它是 2D 网格(我猜图像没有传达这一点),因为同一列中的元素必须具有可变距离以及。在不使用布局的情况下手动创建我的网格可能更聪明吗?就像在布局中有一个父小部件并将我的单元格放在该小部件中? 【参考方案1】:

下面是一个示例程序,它将创建 3 X 3 网格布局(主网格)并用 3 X 3 网格布局(子网格)填充每个单元格。每个子网格将在每一侧添加一个 QPushButton。子网格的剩余空间将由 QSpacerItem 填充。这是要实现的逻辑之一。代码中的注释会详细解释。

void MainWindow::on_cmdGenerate_Grid_clicked()

    QWidget *grdParent;
    grdParent = new QWidget(this->centralWidget());
    grdParent->setGeometry(QRect(0, 0, 300, 300));
    //Main Grid
    QGridLayout *grdParentLayout = new QGridLayout(grdParent);
    grdParentLayout->setObjectName(QStringLiteral("gridLayout"));
    int intTotal=-1;
    //Random position
    int intArray[] = 1,5,7,6,3,4,8,2,0;

    for(int intRow=0;intRow<3;intRow++)
        for(int intCol=0;intCol<3;intCol++)
            intTotal++;
            //Sub Grid that will sit in each cell of the main Grid
            QGridLayout *grdChild = new QGridLayout();
            int intSubTotal=-1;
            for(int intSubRow=0;intSubRow<3;intSubRow++)
                for(int intSubCol=0;intSubCol<3;intSubCol++)
                    intSubTotal++;
                    if(intSubTotal==intArray[intTotal])
                    
                        //Adding push button in any one of the cell of sub grid 
                        QPushButton *p = new QPushButton("Hi",grdParent);
                        p->setFixedSize(33,33);
                        grdChild->addWidget(p , intSubRow, intSubCol, 1, 1);
                    
                    else
                    
                        //Remaining sub grid cells will be filled by Spacer item
                        grdChild->addItem(new QSpacerItem(33,33,QSizePolicy::Fixed,QSizePolicy::Fixed) , intSubRow, intSubCol, 1, 1);
                    
                
            
            //adding sub grid to main grid
            grdParentLayout->addLayout(grdChild,intRow,intCol,1,1);
        
    
    //showing the main grid
    grdParent->setVisible(true);


//Below code will draw boxes to visualize the Main Grid
void MainWindow::paintEvent(QPaintEvent *paint)

    QPainter *p = new QPainter(this);
    for(int intX=0;intX<3;intX++)
        for(int intY=0;intY<3;intY++)
            p->drawRect(intX*100,intY*100,intX+100,intY+100);
        
    

【讨论】:

这适用于少量单元格,但是一旦我有大约 400 个更新方向上的所有单元格就会变慢。切换到 QGraphicsScene 并手动管理间距是否有意义? @inzombiak,是的(QGraphicsView+GraphicsScene)在网格布局+间隔变慢的情况下是最好的。 我接受你的回答,但 QGraphicsView 工作得更好、更容易。【参考方案2】:

在主网格布局内使用辅助网格布局。这些辅助网格布局将包含您的 domino 小部件和定义其位置的四个分隔符 (QSpacerItem)。

这是一个相当复杂的解决方案,但它可以让您完全控制小部件的定位。如果这是您想要的,您可以使用这些辅助网格布局的行拉伸和列拉伸值来获得“随机”放置的良好效果。

我准备了一个小例子:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget class="QWidget" name="Form">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>650</width>
    <height>543</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <layout class="QHBoxLayout" name="horizontalLayout">
   <item>
    <layout class="QGridLayout" name="gridLayout">
     <item row="1" column="0">
      <layout class="QGridLayout" name="gridLayout_5">
       <item row="1" column="2">
        <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>
       <item row="1" column="1">
        <widget class="QPushButton" name="pushButton_4">
         <property name="text">
          <string>PushButton</string>
         </property>
        </widget>
       </item>
       <item row="1" column="0">
        <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 row="0" column="1">
        <spacer name="verticalSpacer_15">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>20</width>
           <height>40</height>
          </size>
         </property>
        </spacer>
       </item>
       <item row="2" column="1">
        <spacer name="verticalSpacer_16">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>20</width>
           <height>40</height>
          </size>
         </property>
        </spacer>
       </item>
      </layout>
     </item>
     <item row="0" column="0">
      <layout class="QGridLayout" name="gridLayout_2">
       <item row="1" column="1">
        <widget class="QPushButton" name="pushButton">
         <property name="text">
          <string>PushButton</string>
         </property>
        </widget>
       </item>
       <item row="1" column="0">
        <spacer name="horizontalSpacer_15">
         <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 row="1" column="2">
        <spacer name="horizontalSpacer_16">
         <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 row="0" column="1">
        <spacer name="verticalSpacer_13">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>20</width>
           <height>40</height>
          </size>
         </property>
        </spacer>
       </item>
       <item row="2" column="1">
        <spacer name="verticalSpacer_14">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>20</width>
           <height>40</height>
          </size>
         </property>
        </spacer>
       </item>
      </layout>
     </item>
     <item row="1" column="1">
      <layout class="QGridLayout" name="gridLayout_7" rowstretch="0,0,0" columnstretch="0,0,0">
       <item row="1" column="1">
        <widget class="QPushButton" name="pushButton_5">
         <property name="text">
          <string>PushButton</string>
         </property>
        </widget>
       </item>
       <item row="1" column="0">
        <spacer name="horizontalSpacer_3">
         <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 row="1" column="2">
        <spacer name="horizontalSpacer_4">
         <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 row="0" column="1">
        <spacer name="verticalSpacer_9">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>20</width>
           <height>40</height>
          </size>
         </property>
        </spacer>
       </item>
       <item row="2" column="1">
        <spacer name="verticalSpacer_10">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>20</width>
           <height>40</height>
          </size>
         </property>
        </spacer>
       </item>
      </layout>
     </item>
     <item row="0" column="2">
      <layout class="QGridLayout" name="gridLayout_4">
       <item row="1" column="0">
        <spacer name="horizontalSpacer_7">
         <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 row="1" column="1">
        <widget class="QPushButton" name="pushButton_3">
         <property name="text">
          <string>PushButton</string>
         </property>
        </widget>
       </item>
       <item row="0" column="1">
        <spacer name="verticalSpacer_3">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>20</width>
           <height>40</height>
          </size>
         </property>
        </spacer>
       </item>
       <item row="2" column="1">
        <spacer name="verticalSpacer_4">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>20</width>
           <height>40</height>
          </size>
         </property>
        </spacer>
       </item>
       <item row="1" column="2">
        <spacer name="horizontalSpacer_8">
         <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>
     </item>
     <item row="2" column="0">
      <layout class="QGridLayout" name="gridLayout_6">
       <item row="1" column="1">
        <widget class="QPushButton" name="pushButton_7">
         <property name="text">
          <string>PushButton</string>
         </property>
        </widget>
       </item>
       <item row="2" column="1">
        <spacer name="verticalSpacer_18">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>20</width>
           <height>40</height>
          </size>
         </property>
        </spacer>
       </item>
       <item row="0" column="1">
        <spacer name="verticalSpacer_17">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>20</width>
           <height>40</height>
          </size>
         </property>
        </spacer>
       </item>
       <item row="1" column="2">
        <spacer name="horizontalSpacer_17">
         <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 row="1" column="0">
        <spacer name="horizontalSpacer_18">
         <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>
     </item>
     <item row="1" column="2">
      <layout class="QGridLayout" name="gridLayout_8">
       <item row="1" column="1">
        <widget class="QPushButton" name="pushButton_6">
         <property name="text">
          <string>PushButton</string>
         </property>
        </widget>
       </item>
       <item row="0" column="1">
        <spacer name="verticalSpacer">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>20</width>
           <height>40</height>
          </size>
         </property>
        </spacer>
       </item>
       <item row="1" column="0">
        <spacer name="horizontalSpacer_5">
         <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 row="1" column="2">
        <spacer name="horizontalSpacer_6">
         <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 row="2" column="1">
        <spacer name="verticalSpacer_2">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>20</width>
           <height>40</height>
          </size>
         </property>
        </spacer>
       </item>
      </layout>
     </item>
     <item row="2" column="1">
      <layout class="QGridLayout" name="gridLayout_9">
       <item row="1" column="1">
        <widget class="QPushButton" name="pushButton_8">
         <property name="text">
          <string>PushButton</string>
         </property>
        </widget>
       </item>
       <item row="2" column="1">
        <spacer name="verticalSpacer_12">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>20</width>
           <height>40</height>
          </size>
         </property>
        </spacer>
       </item>
       <item row="1" column="0">
        <spacer name="horizontalSpacer_13">
         <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 row="0" column="1">
        <spacer name="verticalSpacer_11">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>20</width>
           <height>40</height>
          </size>
         </property>
        </spacer>
       </item>
       <item row="1" column="2">
        <spacer name="horizontalSpacer_14">
         <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>
     </item>
     <item row="2" column="2">
      <layout class="QGridLayout" name="gridLayout_10">
       <item row="1" column="1">
        <widget class="QPushButton" name="pushButton_9">
         <property name="text">
          <string>PushButton</string>
         </property>
        </widget>
       </item>
       <item row="1" column="0">
        <spacer name="horizontalSpacer_9">
         <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 row="1" column="2">
        <spacer name="horizontalSpacer_10">
         <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 row="0" column="1">
        <spacer name="verticalSpacer_5">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>20</width>
           <height>40</height>
          </size>
         </property>
        </spacer>
       </item>
       <item row="2" column="1">
        <spacer name="verticalSpacer_6">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>20</width>
           <height>40</height>
          </size>
         </property>
        </spacer>
       </item>
      </layout>
     </item>
     <item row="0" column="1">
      <layout class="QGridLayout" name="gridLayout_3">
       <item row="1" column="0">
        <spacer name="horizontalSpacer_11">
         <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 row="1" column="1">
        <widget class="QPushButton" name="pushButton_2">
         <property name="text">
          <string>PushButton</string>
         </property>
        </widget>
       </item>
       <item row="1" column="2">
        <spacer name="horizontalSpacer_12">
         <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 row="0" column="1">
        <spacer name="verticalSpacer_7">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>20</width>
           <height>40</height>
          </size>
         </property>
        </spacer>
       </item>
       <item row="2" column="1">
        <spacer name="verticalSpacer_8">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>20</width>
           <height>40</height>
          </size>
         </property>
        </spacer>
       </item>
      </layout>
     </item>
    </layout>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>

【讨论】:

以上是关于更改 QGridLayout 中单个 QWidget 的间距的主要内容,如果未能解决你的问题,请参考以下文章

如何重置QGridLayout中窗口小部件的列跨度?

如何从 QGridLayout 中的单元格中删除小部件

为啥 QGridLayout 不适用于 QLabel

如何停止 QGridLayout 元素的扩展

QScrollArea 搞砸了 QGridLayout:QGridLayout 隐藏并且没有滚动

QT QSlider 边距