pyqt5, почему виджеты перекрываются в версии ООП - PullRequest
0 голосов
/ 26 декабря 2018

Я сократил свою ситуацию до простого: я хочу запрограммировать графический интерфейс в PyQt5, где есть основной QGridLayout с именем grid, в котором есть еще одна сетка gridParamter и виджет QListViewgridParamter есть 2 QLabel

Вот код

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

def window():
    app = QApplication(sys.argv)
    win = QWidget()

    list1 = QListView()

    gridParameter = QGridLayout()

    idxRow = 0
    label_1 = QLabel("I am label one")
    gridParameter.addWidget(label_1, idxRow, 0)

    idxRow = 1
    label_2 = QLabel("I am label two")
    gridParameter.addWidget(label_2, idxRow, 1)

    grid = QGridLayout()
    grid.addLayout(gridParameter, 0, 0)
    grid.setSpacing(2)
    grid.addWidget(list1)

    win.setLayout(grid)
    win.show()
    sys.exit(app.exec_())

if __name__ == '__main__':      
    window()

, который может генерировать графический интерфейс, как я и ожидал.Но когда я пытаюсь переписать его в стиле ООП, то есть

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *


class MainWindow(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        list1 = QListView(self)

        gridParameter = QGridLayout(self)

        idxRow = 0
        label_1 = QLabel("I am label one", self)
        gridParameter.addWidget(label_1, idxRow, 0)

        idxRow = 1
        label_2 = QLabel("I am label two", self)
        gridParameter.addWidget(label_2, idxRow, 1)

        grid = QGridLayout(self)
        grid.addLayout(gridParameter, 0, 0)
        grid.setSpacing(2)
        grid.addWidget(list1)

        self.setLayout(grid)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    mainWin = MainWindow()
    mainWin.show()
    sys.exit( app.exec_() )

, я обнаружил, что label_1 перекрывается с list1, и когда я пытаюсь изменить размер основных окон, list1 всегда принимаетположение сетки (0, 0).

Почему и как это исправить?Спасибо

1 Ответ

0 голосов
/ 26 декабря 2018

Сначала вы должны понять следующее:

  1. Имейте в виду, что следующее выражение:

    lay = FooLayout()
    some_widget.setWidget(lay)
    

эквивалентно:

lay = FooLayout(some_widget)

И то, и другое указывают, что макет будет обрабатывать геометрию дочерних элементов.

С другой стороны, если виджет уже имеет макет, никакой другой макет не может быть установлен, пока предыдущий макет не будет удален.

Так что в вашем случае работает только первая инструкцияа не следующие 2, поэтому сетка макета будет исключена, а представление списка будет поддерживаться только потому, что оно является дочерним для виджета.

gridParameter = QGridLayout(self)
# ...
grid = QGridLayout(self)
# ...
self.setLayout(grid)

В моем случае я избегаю размещения родителей виджетов, чтобы увидеть,Существует проблема, а также я устанавливаю в качестве родителя макета только при необходимости:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets


class MainWindow(QtWidgets.QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()

        list1 = QtWidgets.QListView()

        gridParameter = QtWidgets.QGridLayout()

        idxRow = 0
        label_1 = QtWidgets.QLabel("I am label one")
        gridParameter.addWidget(label_1, idxRow, 0)

        idxRow = 1
        label_2 = QtWidgets.QLabel("I am label two")
        gridParameter.addWidget(label_2, idxRow, 1)

        grid = QtWidgets.QGridLayout(self) # <--- principal layout
        grid.addLayout(gridParameter, 0, 0)
        grid.setSpacing(2)
        grid.addWidget(list1)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    mainWin = MainWindow()
    mainWin.show()
    sys.exit(app.exec_())

В заключение используйте self при необходимости.

...