привязка сигнала к элементам QListWidget - PullRequest
0 голосов
/ 20 апреля 2020

Как мне убедиться, что щелчок по элементу QListWidget открывает соответствующие виджеты в QFrame и что данные, введенные в эти виджеты, сохраняются между элементами переключения списка?

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):

        vbox = QVBoxLayout()
        tab_widget = QTabWidget()
        tab_widget.setStyleSheet('background-color:gainsboro')
        tab_widget.addTab(Setup(), "setup")
        vbox.addWidget(tab_widget)
        self.setLayout(vbox)

class Setup(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):

        hbox = QHBoxLayout()
        splitter = QSplitter(Qt.Horizontal)
        self.list = QListWidget()
        self.list.setStyleSheet("background-color:white")
        QListWidgetItem("vertices", self.list)
        QListWidgetItem("blocks", self.list)
        self.list.itemClicked.connect(self.conv_met)
        splitter.addWidget(self.list)

        self.frame = QFrame()
        self.frame.setFrameShape(QFrame.StyledPanel)
        self.frame.setLineWidth(0.6)

        splitter.addWidget(self.frame)
        hbox.addWidget(splitter)
        self.setLayout(hbox)
        self.show()

    def conv_met(self, item):
        if item.text() == "vertices":
            convertToMeters_layout = QHBoxLayout()
            convertToMeters_lbl = QLabel("convertToMeters")
            convertToMeters_val = QLineEdit("0.1")
            convertToMeters_layout.addWidget(convertToMeters_lbl)
            convertToMeters_layout.addWidget(convertToMeters_val)
            self.frame.setLayout(convertToMeters_layout)
        if item.text() == "blocks":
            block_grad_layout = QGridLayout()
            hexx = QComboBox(self)
            hexx.addItems(["hex"])
            ver_labels = QLineEdit("0 1 2 3 4 5 6 7")

            block_grad_layout.addWidget(hexx, 0, 0)
            block_grad_layout.addWidget(ver_labels, 0, 1)
            self.frame.setLayout(block_grad_layout)

if __name__ == '__main__':

    app = QApplication(sys.argv)
    main_win = Window()
    main_win.show()
    sys.exit(app.exec_())

enter image description here

enter image description here

1 Ответ

0 голосов
/ 20 апреля 2020

Чтобы сохранить данные для элемента, вы можете использовать setData(role, value) для сохранения предыдущих введенных данных и перед переходом на новый текущий элемент.

Обратите внимание, что вы не должны используйте setLayout() более одного раза; фактически, по этой причине ваш пример не работает должным образом, и вы можете увидеть сообщение об ошибке, если вы запустите его из командной строки или командной строки:

QWidget::setLayout: Attempting to set QLayout "" on QFrame "", which already has a layout

Чтобы достичь того, что вы хотите, решение состоит в том, чтобы использовать QStackedWidget , который работает почти как QTabWidget, но не имеет панели вкладок для переключения между «страницами», так как они могут быть только изменено программно с помощью setCurrentIndex() или setCurrentWidget().

class Setup(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):

        hbox = QHBoxLayout()
        splitter = QSplitter(Qt.Horizontal)
        self.list = QListWidget()
        self.list.setStyleSheet("background-color:white")
        self.verticesItem = QListWidgetItem("vertices", self.list)
        self.blocksItem = QListWidgetItem("blocks", self.list)
        self.list.itemClicked.connect(self.conv_met)
        splitter.addWidget(self.list)

        self.frame = QFrame()
        self.frame.setFrameShape(QFrame.StyledPanel)
        self.frame.setLineWidth(0.6)

        frameLayout = QVBoxLayout(self.frame)
        self.stackedWidget = QStackedWidget()
        frameLayout.addWidget(self.stackedWidget)

        self.convertToMeters_widget = QWidget()
        self.stackedWidget.addWidget(self.convertToMeters_widget)
        convertToMeters_layout = QHBoxLayout(self.convertToMeters_widget)
        convertToMeters_lbl = QLabel("convertToMeters")
        self.convertToMeters_val = QLineEdit("0.1")
        convertToMeters_layout.addWidget(convertToMeters_lbl)
        convertToMeters_layout.addWidget(self.convertToMeters_val)

        self.block_grad_widget = QWidget()
        self.stackedWidget.addWidget(self.block_grad_widget)
        block_grad_layout = QGridLayout(self.block_grad_widget)
        hexx = QComboBox()
        hexx.addItems(["hex"])
        self.ver_labels = QLineEdit("0 1 2 3 4 5 6 7")

        block_grad_layout.addWidget(hexx, 0, 0)
        block_grad_layout.addWidget(self.ver_labels, 0, 1)

        splitter.addWidget(self.frame)
        hbox.addWidget(splitter)
        self.setLayout(hbox)

        self.currentItem = None

    def conv_met(self, item):
        if self.currentItem:
            if self.currentItem == self.verticesItem:
                self.currentItem.setData(Qt.UserRole, self.convertToMeters_val.text())
            else:
                self.currentItem.setData(Qt.UserRole, self.ver_labels.text())
        if item == self.currentItem:
            return
        self.currentItem = item
        if item == self.verticesItem:
            self.stackedWidget.setCurrentWidget(self.convertToMeters_widget)
            self.convertToMeters_val.setText(item.data(Qt.UserRole) or '0.1')
        elif item == self.blocksItem:
            self.stackedWidget.setCurrentWidget(self.block_grad_widget)
            self.ver_labels.setText(item.data(Qt.UserRole) or '0 1 2 3 4 5 6 7')

Обратите внимание, что если вы хотите сохранить числовые значения c для "вершин", Вы можете предпочесть использовать QSpinBox (или QDoubleSpinBox для плавающих чисел). Точно так же, если вам нужны только шестнадцатеричные значения, лучше установить inputMask или добавить validator , чтобы убедиться, что введенные значения действительны.

...