首页 > 解决方案 > QTable - 获取 QSpinBox 和 QComboBox 值

问题描述

我无法从 QTable 中获取当前值,其中插入了 QSpinBox 和 QCOmboBox 小部件。我可以从 Qlineedit 获得价值,但除了这个小部件之外没有其他任何东西可以工作。我尝试了几种不同的方式,但它一直返回“无”

在此处输入图像描述

class MainWindow(QDialog):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setWindowTitle("ptb")

        # Main frame
        self.main_layout = QVBoxLayout(self)
        # Layout with 2 buttons and a radio button, part of main_layout
        self.horizontalLayout = QHBoxLayout()

        self.main_frame_tab_widget = QTabWidget()
        self.main_layout.addWidget(self.main_frame_tab_widget)
        self.horizontalLayout = QHBoxLayout()
        self.main_layout.addLayout(self.horizontalLayout)
        self.load_script_button = QPushButton("Load")

        self.horizontalLayout.addWidget(self.load_script_button)

        self.load_script_button.clicked.connect(self.load_script_button_clicked)


        self.main_frame_tab_widget.addTab(self.targeting_tab(), "Targeting")

    def load_script_button_clicked(self):
        model = self.targeting_table.model()
        targeting_table_content = {}
        for row in range(model.rowCount()):
            targeting_table_content[str(model.data(model.index(row, 1)))] = {
                'danger': str(model.data(model.index(row, 2))),
                'loot': str(model.data(model.index(row, 3))),
                'only_if_trapped': str(model.data(model.index(row, 4)))
            }
        print(targeting_table_content)


    def targeting_tab(self):
        targeting_tab = QWidget()

        # Main targeting tab vertical layout, which contains 2 other sublayouts
        targeting_tab_main_layout = QHBoxLayout()

        # Sub vertical layout containing a horizontal layout with 2 buttons and a table bellow the VBox
        inner_left_vertical_layout = QVBoxLayout()
        targeting_tab_main_layout.addLayout(inner_left_vertical_layout)

        # Sub horizontal layout containing 2 buttons
        inner_left_vertical_layouts_sub_horizontal_box = QHBoxLayout()
        inner_left_vertical_layout.addLayout(inner_left_vertical_layouts_sub_horizontal_box)

        # Adding creature
        self.add_creature_button = QPushButton("Add creature")
        inner_left_vertical_layouts_sub_horizontal_box.addWidget(self.add_creature_button)
        self.add_creature_button.clicked.connect(self.add_creature_to_targeting_button_clicked)

        # Deleting creature
        self.delete_creature_button = QPushButton("Delete creature")
        inner_left_vertical_layouts_sub_horizontal_box.addWidget(self.delete_creature_button)
        self.delete_creature_button.clicked.connect(self.delete_creature_button_clicked)

        self.targeting_table = QTableWidget()
        self.targeting_table.setColumnCount(4)
        self.targeting_table.setHorizontalHeaderLabels(['Name', 'Danger', 'Loot', 'Only if trapped'])
        inner_left_vertical_layout.addWidget(self.targeting_table)

        targeting_tab.setLayout(targeting_tab_main_layout)
        return targeting_tab

    def add_creature_to_targeting_button_clicked(self):
        row_count = self.targeting_table.rowCount()
        self.targeting_table.insertRow(row_count)
        self.targeting_table.setItem(row_count, 0, QTableWidgetItem("input_mob_name"))

        self.targeting_table.setCellWidget(row_count, 1, QSpinBox())

        loot_combo_box = QComboBox()
        loot_combo_box.addItems(["Yes", "No"])
        self.targeting_table.setCellWidget(row_count, 2, loot_combo_box)

        only_if_killed_combo_box = QComboBox()
        only_if_killed_combo_box.addItems(["Yes", "No"])
        self.targeting_table.setCellWidget(row_count, 3, only_if_killed_combo_box)

    def delete_creature_button_clicked(self):

        # Shows the  number of delected rows bellow
        rows = sorted(set(index.row() for index in self.targeting_table.selectedIndexes()))
        # Removing the selected rows, if nothing is selected nothing happens
        i = 0
        for index in sorted(rows):
            self.targeting_table.removeRow(index + i)
            i = i - 1
    

if __name__ == '__main__':
    # Create the Qt Application
    app = QApplication(sys.argv)
    # Create and show the form
    form = MainWindow()
    form.show()
        # Run the main Qt loop
        sys.exit(app.exec_())

按下“加载”按钮时,我得到这个结果:{'None': {'danger': 'None', 'loot': 'None', 'only_if_trapped': 'None'}} 如果我改变方式从 Qtable 中获取值的最佳方法是 QlineEdit,但我无法获取 Spinbox 或组合框值

标签: pythonpyqt

解决方案


放置在视图上方的widget与模型无关,它们是独立的,所以不要使用模型,而应该使用cellWidget()方法来获取对应的widget,并通过widget获取信息。

targeting_table_content = []

for row in range(self.targeting_table.rowCount()):
    name = self.targeting_table.item(row, 0).text()
    danger = self.targeting_table.cellWidget(row, 1).value()
    loot = self.targeting_table.cellWidget(row, 2).currentText()
    only_if_trapped = self.targeting_table.cellWidget(row, 3).currentText()
    targeting_table_content.append(
        {
            "name": name,
            "danger": danger,
            "loot": loot,
            "only_if_trapped": only_if_trapped,
        }
    )
print(targeting_table_content)

推荐阅读