简体   繁体   English

如何在 PyQt5 / PySide2 中访问从一个 class 到另一个 class 的属性

[英]How to access attribut from one class to another class in PyQt5 / PySide2

I cannot get access to attribut self.horizontalLayout_Base in class Ui_MainWindow where I want add new widgets.我无法访问 class Ui_MainWindow 中的属性self.horizo ntalLayout_Base ,我想在其中添加新的小部件。

There is:有:

  1. Main class MainWindow which inherits class Ui_MainWindow .主 class MainWindow继承 class Ui_MainWindow
  2. Class Ui_MainWindow creates layout. Class Ui_MainWindow创建布局。
  3. Class Dialog provides additional information and confirmation or cancellation. Class对话框提供附加信息和确认或取消。

Main class MainWindow calls class Dialog .主 class MainWindow调用 class Dialog Class Dialog is queried and then the method tableWidget in class MainWindow is called. Class Dialog被查询,然后调用class MainWindow中的tableWidget方法。 But there is not access to attribut self.horizontalLayout_Base which was creating by class Ui_MainWindow .但是无法访问由 class Ui_MainWindow 创建的属性self.horizo ntalLayout_Base

Is there any way to get access?有什么办法可以访问吗?

Main class MainWindow主 class 主窗口

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    
    def __init__(self, *args, obj=None, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        
        ...
        
        self.setupUi(self)
        
        ...
        
        
    def tableWidget(self):
        if len(list) > 0:
            row = len(list)
            clmn = len(list[0]) 
            self.tableWidget = QTableWidget(row, clmn + 1)
        else:
            return
        self.vbox = QVBoxLayout()

        ...

        Ui_MainWindow.gridLayout_Base.addLayout(self.vbox) # Here I want to get access

Layout class Ui_MainWindow布局 class Ui_MainWindow

class Ui_MainWindow(object):

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1110, 772)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
        MainWindow.setSizePolicy(sizePolicy)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth())
        self.centralwidget.setSizePolicy(sizePolicy)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")

        self.horizontalLayout_Base = QtWidgets.QHBoxLayout() # This is target

        ...

Class Dialog Class 对话框

class Dialog(QDialog):

    NumGridRows = 3
    NumButtons = 4

    def __init__(self, souradnice):
        super(Dialog, self).__init__()
        ...

    def buttonAccepted(self):
        ...

        MainWindow.tableWidget(self)
        self.close()

It seems like you're confusing what classes, instances and their methods are (for this, I strongly suggest you to do some research, as they are fundamental aspects of OOP and cannot be ignored).您似乎对什么是类、实例及其方法感到困惑(为此,我强烈建议您进行一些研究,因为它们是 OOP 的基本方面,不容忽视)。

In tableWidget you cannot access gridLayout_Base from Ui_MainWindow , because that's a class.tableWidget ,您无法从Ui_MainWindow访问gridLayout_Base ,因为那是 class。 Since you're both inheriting from QMainWindow and Ui_MainWindow, and you're calling setupUi(self) that means that all attributes of the ui are actually created as attribute members of the instance , so you can access the layout just by using self.gridLayout_Base .由于您都继承自 QMainWindowUi_MainWindow,并且您正在调用setupUi(self)这意味着 ui 的所有属性实际上都是作为instance的属性成员创建的,因此您只需使用self.gridLayout_Base即可访问布局.
Then, if you're adding a layout, you must use addLayout() , not addWidget() (which is for widgets only).然后,如果要添加布局,则必须使用addLayout() ,而不是addWidget() (仅适用于小部件)。

    def tableWidget(self):
        # ...
        self.gridLayout_Base.addLayout(self.vbox)

Then, I don't know how you're creating and opening the dialog, but you certainly cannot call MainWindow.tableWidget(self) : that would result in calling that method with the dialog instance as first argument (self), so you won't be adding anything to the main window.然后,我不知道您是如何创建和打开对话框的,但您当然不能调用MainWindow.tableWidget(self) :这将导致以对话框实例作为第一个参数(self)调用该方法,所以您赢了不要在主 window 中添加任何内容。

A better and safer way (which is also the commonly accepted practice) is to show the dialog as modal by calling its exec() , and then react to it according to the result.一种更好、更安全的方法(这也是普遍接受的做法)是通过调用其exec()将对话框显示为模态,然后根据结果对其做出反应。 In order to correcty achieve this, you should not call self.close() on the dialog (which results in rejecting it) but self.accept() .为了正确实现这一点,您不应该在对话框上调用self.close() (这会导致拒绝它),而是self.accept()

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    # ...
    def someFunctionToShowDialog(self):
        dialog = Dialog(self)
        if dialog.exec_():
            parameters = dialog.getValues()
            self.tableWidget()
            self.doSomethingWithParameters(parameters)


class Dialog(QDialog):
    # ...
    def buttonAccepted(self):
        self.accept()

    def getValues(self):
        return self.someValue, self.anotherValue

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

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