【问题标题】:binding a signal to QListWidget items将信号绑定到 QListWidget 项
【发布时间】:2020-08-03 05:36:15
【问题描述】:

如何确保单击 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_())

【问题讨论】:

    标签: python python-3.x pyqt pyqt5 qlistwidget


    【解决方案1】:

    为了保留项目的数据,您可以使用setData(role, value) 来存储之前输入的数据,然后再更改为新的当前项目。

    请注意,您不应多次使用setLayout();事实上,由于这个原因,您的示例无法按预期工作,如果您从 shell 或命令提示符运行它,您可能会看到错误消息:

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

    要实现你想要的,解决方案是使用QStackedWidget,它的工作方式几乎类似于 QTabWidget,但没有用于在“页面”之间切换的标签栏,因为它们只能使用 @987654323 以编程方式更改@ 或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')
    

    请注意,如果您想存储“顶点”的数值,您可能更喜欢使用 QSpinBox(或 QDoubleSpinBox 用于浮点数)。同样,如果您只需要十六进制值,最好设置inputMask 或添加validator 以确保输入的值有效。

    【讨论】:

    • 非常感谢! QStackedWidget - 这正是我所需要的。
    猜你喜欢
    • 2020-10-10
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 2015-05-18
    • 1970-01-01
    • 2012-05-27
    相关资源
    最近更新 更多