簡體   English   中英

PyQt5 QGridLayout 大小不正確

[英]PyQt5 QGridLayout sizing incorrect

我在 pyqt5 中遇到了 QGridLayout 的一些問題。 我正在嘗試制作一個 GUI,它的一側有一堆按鈕,另一側有一張桌子,還有一個占據整個窗口底部的圖。 這是我做過的第一個程序,所以我可能遇到的問題比我知道的要多。

我已經在 QTableWidget 中安排了按鈕,主要的 QTableWidget 包含幾個用戶可以輸入數據的字段。 我希望數據輸入表的大小比按鈕表大,但是在這個答案中調整它的大小似乎沒有任何作用。 無論我輸入什么 columnSpan 條目,按鈕表都會變大。我做錯了什么?

以下是相關的代碼位:

class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        self.setGeometry(50, 50, 700, 1000)
        self.home()

    def home(self):
        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)

        self.button_table = QTableWidget(self)  
        self.layer_add = QPushButton("Add layer", self)       
        self.plotter = QPushButton("plot transmission", self)

        self.layer_table = QTableWidget(self)

        self.graphWidget = pg.PlotWidget(self)

        self.grid = QGridLayout()
        self.grid.setSpacing(10)
        self.grid.addWidget(self.button_table, 0, 0, 1, 1)
        self.grid.addWidget(self.layer_table, 0, 1, 1, 3)
        self.grid.addWidget(self.graphWidget, 1, 0, 1, 4)      
        self.centralWidget().setLayout(self.grid)
        self.show()

我塗鴉了我最希望發生的事情......這是上面代碼的樣子

紅色的是我希望發生的事情。

編輯:我不明白為什么,如果我將左側表格的 QGridLayout columnSpan 設置為 1,右側表格的 QGridLayout columnSpan 設置為 3,則左側表格仍然明顯更寬。 我願意學習如何解決這個問題,了解如何使左側表格自動縮小到其中的按鈕大小,或者提供替代布局建議。 謝謝你的幫助!

啊,原來在第 1 列上使用 setColumnStretch 解決了這個問題。 我還將左表更改為 QVBoxLayout 並使用 QGridLayout.addLayout 將其放入,因此現在一切看起來更好

不管選擇的列數如何,我仍然不太明白為什么 QGridLayout 上的兩個表的寬度不相等。

當您回答自己的問題時,似乎您通過刪除第一個表格來改變行為(此外,更改第一列拉伸的調整大小模式與您的問題沒有太大關系)。 所以我正在回答您的 [編輯] 問題,即使它缺少您將按鈕添加到第一個表格的部分。

主要問題是您為第二個表設置的列跨度太大:

    self.grid.addWidget(self.button_table, 0, 0, 1, 1)
    self.grid.addWidget(self.layer_table, 0, 1, 1, 3) # <- 3 columns!
    self.grid.addWidget(self.graphWidget, 1, 0, 1, 4)      

在上面的代碼中,您告訴布局layer_table列跨度為 3 列。 即使您實際上沒有使用三列,通過這樣做,布局也會認為第二個表格(可能)比第一個表格占用更多的空間。
通常,QGridLayout 將為此使用columnStretch屬性,但由於默認情況下所有列和行的拉伸為 0,因此它將使用跨度作為參考。

實際上,使用以下內容:

    self.grid.addWidget(self.button_table, 0, 0, 1, 1)
    self.grid.addWidget(self.layer_table, 0, 1, 1, 1) # <- 1 column!
    self.grid.addWidget(self.graphWidget, 1, 0, 1, 2)      

與此相同:

    self.grid.addWidget(self.button_table, 0, 0, 1, 1)
    self.grid.addWidget(self.layer_table, 0, 1, 1, 3) # <- 3 columns!
    self.grid.addWidget(self.graphWidget, 1, 0, 1, 4)      
    self.grid.setColumnStretch(0, 1)
    self.grid.setColumnStretch(1, 1)

在第一種情況下,列跨度為 1(一個小部件,一列),並且由於兩個小部件的類型相同,因此它們將使用可用水平空間的一半。 在第二個中,右表的列跨度為 3(如您的代碼中所示),第一列第二列的拉伸為 1,第三和第四列的拉伸為 0,這意味着占據第二個的小部件,第三列和第四列將具有與占據第一列的小部件相同的可用空間,從而獲得在這兩個小部件之間平均划分的水平空間。

col1 | col2 | col3 | col4
  1  |   1  |   0  |  0

由於第二個表占據了第 2 到 4 列,因此它的長度為 1 (1 + 0 + 0)。 布局使用伸展來平均划分小部件之間的空間(考慮它們的大小提示、最小大小提示或設置時的最小/最大大小):伸展是整數值的總和,然后布局使用比例在總和和這些值之間調整小部件的大小。


為確保第一個表僅使用顯示其內容所需的最小空間,您需要執行以下操作:

  1. sizeAdjustPolicy (這是每個 QAbstractScrollArea 后代的屬性,包括每個項目視圖)設置為AdjustToContents 這將使表格“告訴”布局其大小提示基於其最小內容;
  2. 設置水平標題調整大小模式以將其所有部分(如列中)調整為它們的內容;
  3. 將表格的水平尺寸策略設置為Maximum 術語“最大”可能違反直覺,但這意味着小部件的大小不能大於其大小提示; 盡管如此,如果任何其他小部件需要空間(但不小於minimumSizeHint ),它仍然可以縮小,因此,或者,您可以使用Fixed (意味着它甚至不能縮小),但通常最好允許小部件無論如何縮小,如果布局過於擁擠,用戶需要將窗口縮小;
class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        self.setGeometry(50, 50, 700, 1000)
        self.home()

    def home(self):
        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)

        self.button_table = QTableWidget(self)
        self.button_table.setRowCount(3)
        self.button_table.setColumnCount(1)

        # set the sizeHint of the table view (actually, its ancestor class,
        # QAbstractScrollArea) to the minimum size required to show its contents
        self.button_table.setSizeAdjustPolicy(self.button_table.AdjustToContents)

        # set all sections of the horizontal headers to adjust themselves to
        # their contents
        self.button_table.horizontalHeader().setSectionResizeMode(
            QHeaderView.ResizeToContents)

        # get the current sizePolicy and set it to Maximum, meaning that it will
        # use its sizeHint as "maximum": it can expand, but there's no need for
        # that, so if any other sibling widget requires more space, it can use it
        policy = self.button_table.sizePolicy()
        policy.setHorizontalPolicy(policy.Maximum)
        # apply the changed policy
        self.button_table.setSizePolicy(policy)

        self.layer_add = QPushButton("Add layer", self)       
        self.plotter = QPushButton("plot transmission", self)
        # I restored the following lines, which were missing in your edit
        self.button_table.setCellWidget(0, 0, self.layer_add)
        self.button_table.setCellWidget(1, 0, self.plotter)

        self.layer_table = QTableWidget(self)

        self.graphWidget = pg.PlotWidget(self)

        self.grid = QGridLayout()
        self.grid.setSpacing(10)
        self.grid.addWidget(self.button_table, 0, 0, 1, 1)
        self.grid.addWidget(self.layer_table, 0, 1, 1, 1)
        self.grid.addWidget(self.graphWidget, 1, 0, 1, 2)
        self.centralWidget().setLayout(self.grid)

如您所見,現在左表僅使用所需的最小寬度,基於水平標題寬度(加上垂直標題寬度),而后者又基於每列的最大寬度之和。

表格的屏幕截圖正確調整到其內容

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM