【问题标题】:How to update values between PyQt5 Tabs created as classes如何更新作为类创建的 PyQt5 选项卡之间的值
【发布时间】:2019-05-04 04:40:37
【问题描述】:

我在 PyQT5 中有 2 个选项卡创建为单独的类。第一个类(选项卡)是加载excel文件,第二个是设置删除不需要的行的规则。当我加载文件时,我需要将所有标题发布到其他选项卡中的 QComboBox 以便我可以创建规则。无法让它发挥作用。

import sys
from PyQt5.QtWidgets import *
import pandas as pd


class BOMAppWindow(QDialog):
    def __init__(self):
        super().__init__()

        self.setGeometry(250, 150, 1400, 600)

        mainTabWidget = QTabWidget()     # --------- TABS UI ----------
        mainTabWidget.addTab(FileOpenTab(), "File Open")
        mainTabWidget.addTab(RowRemoveRulesTab(), "Row Delete Rules")

        mainVbox = QVBoxLayout()
        mainVbox.addWidget(mainTabWidget)

        self.setLayout(mainVbox)


df = pd.DataFrame()   # pandas dataframe as container for excel spreadsheet
header_list = []


class FileOpenTab(QDialog):
    def __init__(self):
        super().__init__()

        vbox = QVBoxLayout()
        h_top_box = QHBoxLayout()
        excel_load_button = QPushButton("Open Excel File")
        h_top_box.addWidget(excel_load_button)  # ---- Adding Widgets to HBox

        # ----------------  Adding Table Widget -----------

        self.excel_table = QTableWidget()

        vbox.addLayout(h_top_box)         #-----Create Vertical Box Layout
        vbox.addWidget(self.excel_table)
        self.setLayout(vbox)

        excel_load_button.clicked.connect(self.set_file_data)  
# ----------- Open Excel Button Clicked Event
        self.show()

    def file_path(self):       # -----------    file dialog box
        filter_excel_only = "Excel Files (*.xlsx)"
        filename = QFileDialog.getOpenFileName(self, 'Open Excel File', "", filter_excel_only)
        return filename[0]


    def set_file_data(self):                
        path_text = self.file_path()
        if path_text:
            global df
            df = pd.read_excel(path_text, na_filter=False)  
            self.post_dataframe(df)
            RowRemoveRulesTab().update_select_list()

    def post_dataframe(self, dataframe):
        column_count = dataframe.shape[1]
        row_count = dataframe.shape[0]
        self.excel_table.setColumnCount(column_count)
        self.excel_table.setRowCount(row_count)
        self.excel_table.setHorizontalHeaderLabels(list(dataframe.columns))

    def header_list(self):
        return list(df.columns)


class RowRemoveRulesTab(QDialog):
    def __init__(self):
        super().__init__()

        hbox = QHBoxLayout()
        groupBox1 = QGroupBox("Rule 1:")
        vbox1 = QVBoxLayout()

        self.rule1select = QComboBox()
        self.rule1select.addItems(FileOpenTab().header_list())

        vbox1.addWidget(self.rule1select)

        groupBox1.setLayout(vbox1)
        hbox.addWidget(groupBox1)

        self.setLayout(hbox)

        self.show()

    def update_select_list(self):
        self.rule1select.clear()
        self.rule1select.addItems(FileOpenTab().header_list())
        print(FileOpenTab().header_list())


app = QApplication(sys.argv)
bomAppWindow = BOMAppWindow()
bomAppWindow.show()
app.exec()

我需要第二个选项卡中的最后一个函数(或任何其他处理方式) update_select_list(self): 使用第一个 FileOpenTab 类中加载的 excel 文件中的标题列表更新 QComboBox。现在 QComboBox 在文件加载后保持空白。

【问题讨论】:

    标签: python pyqt pyqt5 qtabwidget


    【解决方案1】:

    您的问题的关键是您假设每次执行 FileOpenTab() 时它总是相同的小部件,但事实并非如此。 RowRemoveRulesTab 也是如此。相反,您必须将对象存储在变量中并重用它。

    另一方面你有设计问题,在这种情况下你必须使用Single responsibility principle,它表示每个类都有一个功能,并且必须为其他对象提供访问信息的方法,在Qt/PyQt中最简单传输信息的方式是通过信号,在这种情况下,当加载数据帧时,将发出带有新标头的信号,并且该信号必须连接到另一个类的方法,以便它更新 QComboBox 的信息。

    from PyQt5 import QtCore, QtGui, QtWidgets
    import pandas as pd
    
    
    class FileOpenTab(QtWidgets.QWidget):
        headersChanged = QtCore.pyqtSignal(list)
    
        def __init__(self, parent=None):
            super(FileOpenTab, self).__init__(parent)
    
            excel_load_button = QtWidgets.QPushButton(
                "Open Excel File", clicked=self.load_file
            )
            self.excel_table = QtWidgets.QTableWidget()
    
            lay = QtWidgets.QVBoxLayout(self)
            lay.addWidget(excel_load_button)
            lay.addWidget(self.excel_table)
    
        @QtCore.pyqtSlot()
        def load_file(self):
            filter_excel_only = "Excel Files (*.xlsx)"
            filename, _ = QtWidgets.QFileDialog.getOpenFileName(
                self, "Open Excel File", "", filter_excel_only
            )
            if filename:
                df = pd.read_excel(filename, na_filter=False)
                self.fill_table(df)
    
        def fill_table(self, dataframe):
            row_count, column_count = dataframe.shape
            self.excel_table.setColumnCount(column_count)
            self.excel_table.setRowCount(row_count)
            headers = list(dataframe.columns)
            self.excel_table.setHorizontalHeaderLabels(headers)
            self.headersChanged.emit(headers)
    
    
    class RowRemoveRulesTab(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super(RowRemoveRulesTab, self).__init__(parent)
    
            self.rule_select = QtWidgets.QComboBox()
            group_box = QtWidgets.QGroupBox("Rule 1:")
    
            vbox = QtWidgets.QVBoxLayout()
            vbox.addWidget(self.rule_select)
            group_box.setLayout(vbox)
    
            lay = QtWidgets.QVBoxLayout(self)
            lay.addWidget(group_box)
    
        @QtCore.pyqtSlot(list)
        def update_items(self, items):
            self.rule_select.clear()
            self.rule_select.addItems(items)
    
    
    class BOMAppWindow(QtWidgets.QMainWindow):
        def __init__(self, parent=None):
            super(BOMAppWindow, self).__init__(parent)
    
            file_open_tab = FileOpenTab()
            row_remove_rules_tab = RowRemoveRulesTab()
    
            file_open_tab.headersChanged.connect(row_remove_rules_tab.update_items)
    
            mainTabWidget = QtWidgets.QTabWidget()
            mainTabWidget.addTab(file_open_tab, "File Open")
            mainTabWidget.addTab(row_remove_rules_tab, "Row Delete Rules")
    
            self.setCentralWidget(mainTabWidget)
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        w = BOMAppWindow()
        w.show()
        sys.exit(app.exec_())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多