简体   繁体   English

将信号绑定到 QListWidget 项

[英]binding a signal to QListWidget items

How do I make sure that clicking on a QListWidget item opens the corresponding widgets in the QFrame and that the data entered in these widgets is saved between switching list items?如何确保单击 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_())

在此处输入图像描述

在此处输入图像描述

In order to keep data for an item, you can use setData(role, value) to store the previous entered data and before changing to the new current item.为了保留项目的数据,您可以使用setData(role, value)来存储以前输入的数据,然后再更改为新的当前项目。

Note that you should not use setLayout() more than once;请注意,您不应多次使用setLayout() in fact, your example doesn't work as expected for this reason, and you could see the error message if you run it from a shell or command prompt:事实上,由于这个原因,您的示例无法按预期工作,如果您从 shell 或命令提示符运行它,您可能会看到错误消息:

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

To achieve what you want, the solution is to use QStackedWidget , which works almost like a QTabWidget, but doesn't have a tab bar to switch between "pages", as they can only be changed programmatically using setCurrentIndex() or setCurrentWidget() .为了实现您想要的,解决方案是使用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')

Note that if you want to store numeric values for the "vertices", you might prefer to use a QSpinBox (or QDoubleSpinBox for floating numbers).请注意,如果您想存储“顶点”的数值,您可能更喜欢使用 QSpinBox(或 QDoubleSpinBox 用于浮点数)。 Similarly, if you need only hexadecimal values, it's better to set an inputMask or add a validator to ensure that the entered values are valid.同样,如果您只需要十六进制值,最好设置一个inputMask或添加一个验证器以确保输入的值是有效的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM