Python 3.x PyQt5-在一个选项卡中单击按钮时,执行';行动';在另一个选项卡范围问题中

Python 3.x PyQt5-在一个选项卡中单击按钮时,执行';行动';在另一个选项卡范围问题中,python-3.x,class,oop,pyqt5,Python 3.x,Class,Oop,Pyqt5,为了使代码易于管理,我将所有内容都划分为类。TabWidget实例在窗口中调用,tablet类在选项卡类中调用,等等 如何在Window类之外将功能/操作拆分为自己的类 例如:如果我单击顶部选项卡小部件(tabIn.tablet1.btnApply)中的应用按钮,我如何以编程方式侦听此事件并在底部选项卡小部件(tabOut.tablet1.textGreeting)上执行一些操作(例如写“Hi”)?目前我可以在Window类内部处理这个问题,但随着代码的增长,它将变得非常庞大,所以我希望转移到它

为了使代码易于管理,我将所有内容都划分为类。TabWidget实例在窗口中调用,tablet类在选项卡类中调用,等等

如何在Window类之外将功能/操作拆分为自己的类

例如:如果我单击顶部选项卡小部件(tabIn.tablet1.btnApply)中的应用按钮,我如何以编程方式侦听此事件并在底部选项卡小部件(tabOut.tablet1.textGreeting)上执行一些操作(例如写“Hi”)?目前我可以在Window类内部处理这个问题,但随着代码的增长,它将变得非常庞大,所以我希望转移到它自己的类

我对OOP和PyQt非常陌生

版本: 代码
我不确定我是否理解你的要求。你说的“我如何能以编程方式监听”是什么意思?无论如何,我必须说,您试图“保持代码可管理”存在一些问题,其中一些问题优先于“可管理性”。首先,请记住,重构和“类拆分”应该可以改善代码的组织和可读性(例如,在
平板电脑中有3个独立的函数是毫无意义的)
TableTablet
继承自两个Qt子类,Qt不能很好地处理多重继承,而您的继承也没有多大意义。那么,为什么要->->从
选项卡中的QTabWidget子类化,然后在其中创建一个新的QTabWidget(
选项卡
)?您为
ItemTablet
TableTablet
创建的
QWidget()
有什么意义?一个小部件的参数旨在成为一个父部件,拥有一个空的QWidget有什么用呢?在考虑重构之前(重构应该小心进行,因为它应该是实用的),我建议您解决上述问题,它们更重要。除此之外,如果经过深思熟虑,拥有一个“大规模”的课程并不是一个问题,有时比拥有几十个毫无意义的小班要好。@musicamante,我所说的倾听是指如何获得一个按钮点击事件。我的示例简化为在实际代码中,每个选项卡小部件中有3个平板电脑,每个平板电脑都有许多标签、组合框、按钮等。将其留在窗口类中会使代码无法管理。你说平板电脑有3个功能是没有意义的是什么意思?你看过密码了吗?这些功能由每个tablet类使用。关于继承Qwidget作为参数是错误的,我认为你是对的。@musicamante请详细说明为什么你认为Tablet类中的3个独立函数是没有意义的,因为所有继承的类都使用这些函数。从QTabWidget中进行子类化以扩展其功能,并将该类用作(平板电脑的)实例创建者以从窗口中移动该代码。您建议我如何构造代码来处理两个TabWidget,它们彼此通信,而不需要过度扩展窗口类?除非您确实需要高度模块化的实现,否则过度的子类化弊大于利
stdFormLayout
stdButtons
是高度相互依赖的(因此在不同的函数中使用它们几乎没有什么好处,特别是考虑到这些函数非常简单,而且也只调用一次)。如前所述,你不应该过于沉迷于拥有一个“小”的主课。分离对象类主要是为了oop的好处:模块化和可重用性;如果最终只有两个非常相似的类,那么使用专门的函数。
python                 3.7.3
PyQt5                  5.15.4
PyQt5-Qt5              5.15.2
PyQt5-sip              12.8.1
"""
Initialises Window, Sets out the geometry management, and adds Widgets
"""
import sys

from PyQt5.QtCore import pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import (
  QApplication, QGridLayout, QMainWindow, QTableWidgetItem, QWidget
)

from PyQt5.QtWidgets import (
  QComboBox, QFormLayout, QHBoxLayout, QVBoxLayout,
  QLabel, QPushButton, QTabWidget, QTableWidget, QWidget
)


class Window(QMainWindow):
    """Create an instance of Window. Sets up main Window"""
    # my_signal = pyqtSignal(int)
    def __init__(self):
        super().__init__()
        self.setMinimumSize(1000, 800)
        self.centralWgt = QWidget()  # create central widget
        self.setCentralWidget(self.centralWgt)  # set central widget
        self.tabIn = InputTab()  # create input tab widget
        self.tabOut = OutputTab()  # create input tab widget
        self.windowLayout()  # set window layout

        # TODO: Move this and "test" to a class to keep Window minimal
        self.tabIn.tablet1.btnApply.clicked.connect(self.test)

    def test(self):
        """
        When tabIn tablet1 btnApply pressed, Do something in tabOut tablet1
        """
        self.tabOut.tablet1.textGreeting.setText(“Hello”)
        print("Here!")

    def windowLayout(self):
        """Handles the main windows layout"""
        self.layout = QGridLayout()
        self.centralWgt.setLayout(self.layout)
        self.layout.addWidget(self.tabIn, 0, 1)  # Add widgets to layout
        self.layout.addWidget(self.tabOut, 1, 1, 2, 1)  # Add widgets to layout
        # Handle window and widget resizing
        self.layout.setColumnStretch(0, 1)
        self.layout.setColumnStretch(1, 1)
        self.layout.setRowStretch(0, 1)
        self.layout.setRowStretch(1, 1)
        self.layout.setRowStretch(2, 1)


# TAB MANAGEMENT


class Tabs(QTabWidget):
    """Tabs master class"""
    def __init__(self):
        super().__init__()
        self.tabs = QTabWidget()  # Initialise Tab Widget
        self.layout = QVBoxLayout()  # Define Tab Widget Layout
        self.setLayout(self.layout)  # Set Tab Widget Layout
        self.setStyleSheet('QTabBar { font-size: 12pt;}')  # Set tab title size


class InputTab(Tabs):
    """Creates and sets up the InputTab Class. Inherits from Tab Class"""
    def __init__(self):
        super().__init__()
        self.tablet1 = ItemTablet(QWidget())  # Initialise tablet
        self.tabs.addTab(self.tablet1, "Item Queries")  # Add tablet
        self.layout.addWidget(self.tabs)  # Add tablets to layout


class OutputTab(Tabs):
    """Creates and sets up the OutputTab Class. Inherits from Tab Class"""
    def __init__(self):
        super().__init__()
        self.tablet1 = TableTablet(QWidget())  # Initialise tablet
        self.tabs.addTab(self.tablet1, "Output - Item Table")  # Add tablet
        self.layout.addWidget(self.tabs)  # Add tablets to layout


# TABLET MANAGEMENT #


class Tablets(QTableWidget):
    """The Tablets master class. Contains shared methods, variables"""
    def __init__(self, widget):
        super().__init__()
        self.widget = widget  # set tablet widget as given widget type
        self.layout = QVBoxLayout()  # create tablet outer layout
        self.setLayout(self.layout)  # set tablet outer layout
        self.setStyleSheet('font-size: 10pt;')  # Set tablet font size

    def populateForm(self, formFields):
        """Populates a form layout with dict key value pairs"""
        for k, v in formFields.items():
            self.frmLayout.addRow(k, v)  # Add items to tablet form layout

    def stdButtons(self):
        """Adds Apply and Clear buttons to bottom of tablet."""
        self.btnApply = QPushButton(text="Apply")
        self.btnClear = QPushButton(text="Clear")
        self.btnLayout.addWidget(self.btnApply)
        self.btnLayout.addWidget(self.btnClear)

    def stdFormLayout(self):
        """Creates a Form with horizontal buttons at bottom"""
        self.frmLayout = QFormLayout()  # create tablet sublayout
        self.btnLayout = QHBoxLayout()  # create tablet sublayout
        self.layout.addLayout(self.frmLayout)  # set tablet sublayout
        self.layout.addLayout(self.btnLayout)  # set tablet sublayout


class ItemTablet(Tablets):
    """Handles Item Tablet"""
    def __init__(self, widget):
        super().__init__(widget)
        self.stdFormLayout()  # choose stdFormLayout as a sublayout
        self.stdButtons()  # add stdButtons to sublayout
        # create form items
        self.lblItems = QLabel("Item name")
        self.cmbItems = QComboBox()
        self.cmbItems.addItems(["1", "2", "3"])

        # add form items to dict to setup widget associations
        self.formFields = {
            self.lblItems: self.cmbItems,
        }
        self.populateForm(self.formFields)  # add items to form layout


class TableTablet(Tablets, QTableWidget):
    """Handles the output table tablet"""
    def __init__(self, widget):
        super().__init__(widget)
        self.style = "::section{Background-color:lightgray;border-radius:9px;}"
        self.header = self.horizontalHeader()
        self.header.setStyleSheet(self.style)
        self.textGreeting = QLineEdit()
        self.layout.addWidget(self.textGreeting)


if __name__ == "__main__":
    app = QApplication([])
    window = Window()
    window.show()
    sys.exit(app.exec_())