【问题标题】:Qt Designer layouts don't respect pre-defined geometryQt Designer 布局不尊重预定义的几何图形
【发布时间】:2014-04-09 11:26:39
【问题描述】:

我正在 Qt Designer 中创建一个新的 QWidget,其中包含一个 QLabel 和一个 QTextEditframe。我可以设置所有这些元素的几何形状,并将它们设置为fixed,这样它们的高度/宽度就不会改变:

在此示例中,我的 QLabelQLineEdit 位于其父框架的右上角。如果我现在为框架设置布局(我需要这样做以确保在调整窗口大小时元素保持在正确的位置,或者如果框架是QScrollArea 的主要小部件),那么元素将被移动,即使在框架的参考:

在这种情况下,窗体布局被应用到框架;我们可以看到QLabel 的 (X,Y) 坐标已从 (0,0) 变为 (10,10)。无论我是否事先将这两个元素包装在一个垂直框架中,都会发生这种情况。

鉴于我试图通过手动设置元素坐标来创建非常精确的布局,因此在应用布局时让它们移动看似随机的数量非常令人沮丧。我该怎么办?!我想我误解了什么,但我不知道是什么!

【问题讨论】:

  • 我认为您的问题是由使用表单布局以及默认边距和间距问题引起的。无论如何,我已经用适用于您的示例的解决方案更新了我的答案。

标签: python layout pyqt qt-designer


【解决方案1】:

布局具有默认边距和间距,其精确值由当前小部件样式提供。

您可以通过单击布局的父小部件来覆盖默认值,然后向下滚动到属性编辑器的底部,您将在其中看到具有相关值的布局部分(-1 表示“使用默认值")。

编辑

我没有说清楚的一件事是,每次您中断和重置布局时,布局边距和间距都会恢复为默认值!这有时会很烦人,但确实有意义,因为每次执行此操作时都会创建一个新布局。

无论如何,我认为问题的真正根源实际上是您使用的是表单布局,它可能比其他布局灵活得多。我认为你应该做的是将标签和行编辑放在一个水平布局中,最后有一个水平分隔符。然后在Horizo​​ntal Layout下方放置一个Vertical Spacer,并在Frame中添加一个Vertical Layout。这种安排将使标签和行编辑保持在框架的左上角。有了这些,您最终可以将垂直布局边距设置为零以获得所需的结果。

这是一个 .ui 文件,您可以对其进行测试,看看它们是如何结合在一起的:

<?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>316</width>
    <height>150</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <layout class="QGridLayout" name="gridLayout">
   <item row="0" column="0">
    <widget class="QFrame" name="frame">
     <property name="frameShape">
      <enum>QFrame::StyledPanel</enum>
     </property>
     <property name="frameShadow">
      <enum>QFrame::Raised</enum>
     </property>
     <layout class="QVBoxLayout" name="verticalLayout">
      <property name="spacing">
       <number>0</number>
      </property>
      <property name="margin">
       <number>0</number>
      </property>
      <item>
       <layout class="QHBoxLayout" name="horizontalLayout">
        <property name="spacing">
         <number>0</number>
        </property>
        <item>
         <widget class="QLabel" name="label">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
            <horstretch>0</horstretch>
            <verstretch>0</verstretch>
           </sizepolicy>
          </property>
          <property name="minimumSize">
           <size>
            <width>75</width>
            <height>0</height>
           </size>
          </property>
          <property name="text">
           <string>TextLabel</string>
          </property>
         </widget>
        </item>
        <item>
         <widget class="QLineEdit" name="lineEdit">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
            <horstretch>0</horstretch>
            <verstretch>0</verstretch>
           </sizepolicy>
          </property>
          <property name="minimumSize">
           <size>
            <width>100</width>
            <height>0</height>
           </size>
          </property>
         </widget>
        </item>
        <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>
       </layout>
      </item>
      <item>
       <spacer name="verticalSpacer">
        <property name="orientation">
         <enum>Qt::Vertical</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>20</width>
          <height>106</height>
         </size>
        </property>
       </spacer>
      </item>
     </layout>
    </widget>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>

【讨论】:

  • 虽然这并没有完全回答我的问题,但它确实激发了我重新思考我的布局策略!
  • 有点离题,但像 ChrisW 一样,“鼓舞人心”。我遇到了一个奇怪的问题,即 QFormLayout 正在“压缩”所有小部件,即使在设计器中显示了默认间距 (6) 也是如此。我在阅读后手动更改它我将它更改为 -1,它现在可以正确显示小部件。
【解决方案2】:

布局的重点是它们控制其中元素的大小和位置。这就是他们的工作方式。如果他们无法控制小部件的几何形状,那么在调整大小时他们会做什么?

不要试图严格控制所有东西的大小和位置,而是使用布局来传达设计意图:这两个控件属于一起,这些相同的项目应该在一个列中,等等。

【讨论】:

  • 嗯,也许我做错了整个事情?我布置了元素(在我的现实生活实例中,我使用QScrollAreas 和QTabWidget),为了正确显示这些元素,它们必须应用布局。 QWidget 必须应用网格布局(afaik?)以确保在调整小部件大小时元素(相对)保持在正确的位置。我只使用 (x,y) 坐标和最小/最大尺寸设置几何图形,以获得非常精确的布局(包含列和行)
  • @ChrisW:x 和 y 坐标完全受布局控制。您设置的任何内容都将被覆盖/忽略。将遵守最小/最大尺寸(但如果您必须具有固定尺寸,我建议仅设置最小尺寸并使用“固定”的 sizePolicy)。
  • @ChrisW:我不认为 ekhumoro 是说修改边距会导致 x 和 y 受到尊重,他是说边距是控制布局定位行为的一种方式。
  • @ChrisW:当您进行“精确”布局时,您真正关心的是绝对 x 和 y 坐标,还是达到目的的一种手段? (提示:我希望是后者。)您应该更加关注一致的边距/间距、小部件之间的对齐以及相关小部件的接近度。所有这些事情都可以通过布局轻松完成。布局只是实现相同目的的一种不同(通常更好)的手段。
  • @ChrisW。我赞同史蒂夫在这些 cmets 中所说的一切。设置精确的尺寸和位置是很少使用的最后手段。 Qt 的布局管理并不完美,但如果您使用它,它会在 95% 的时间里提供非常好的结果。您确实需要放弃一些控制以充分利用它,但是通过深入了解系统的工作原理,您将重新获得大部分控制。这将随着练习而来。
【解决方案3】:

影响定位和尺寸的关键要素需要注意:

  1. 基本表单的布局
  2. 表单中的布局
  3. 小部件 sizepolicy 和小部件最小和最大尺寸值

所有元素以级联方式协同工作。通常需要多次尝试和 CTRL+R 来评估表单的外观和调整大小的性质,但通常是这 3 件事。

【讨论】:

    猜你喜欢
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    • 1970-01-01
    • 1970-01-01
    • 2021-09-17
    • 2011-03-30
    • 2016-07-05
    相关资源
    最近更新 更多