如何通过单击QPushButton

问题描述

我有一个带有两个标签的界面:在第一个标签中,我要求用户输入参数,在第二个标签中,我要打印以下QTableWidget。

所以基本上在第一个选项卡上我有一个QPushButton,我将其称为process,通常,当我按下它时,我想将信息发送到第二个选项卡。

现在,我刚刚尝试显示一个带有QTableWidget和良好参数的新窗口:

class Parameters(QWidget):
  
    def __init__(self):
        super(Parameters,self).__init__()

        self.matrixsize = QLineEdit()
        bouton = QPushButton("define matrix_size")
        bouton.clicked.connect(self.appui_bouton)
        self.halfmatrix = QCheckBox()
        self.halfmatrix.toggled.connect(self.on_checked)

   
        self.define_matrix_size = qgroupbox('Define Parameters')
        layout = qgridLayout()
        layout.addWidget(self.matrixsize,1,)
        layout.addWidget(bouton,1)
        layout.addWidget(QLabel('select half size mode'
                                ),1)
        layout.addWidget(self.halfmatrix,1)
        self.define_matrix_size.setLayout(layout)

        process = QPushButton('process')
        process.clicked.connect(self.process)

        self.matrix = QTableWidget()
        self.layout = qgridLayout()
        self.layout.addWidget(self.define_matrix_size)
  
        self.layout.addWidget(matrix)
        self.layout.addWidget(process)

        self.setLayout(self.layout)

    def matrix_size(self):
        if self.matrixsize.text() == "":
            return 0

        else:
            return int(self.matrixsize.text())

       def appui_bouton(self):
        taille = self.matrixsize()
        self.matrix.deleteLater()
        if self.halfmatrix.isChecked():
            self.on_checked()

        else:
            self.matrix = QTableWidget()
            self.matrix.setColumnCount(taille)
            self.matrix.setRowCount(taille)
            self.layout.addWidget(self.matrix)
            self.update()
            self.setLayout(self.layout)

  


    def keyPressEvent(self,qKeyEvent):
        print(qKeyEvent.key())
        if qKeyEvent.key() == Qt.Key_Return or qKeyEvent.key() == Qt.Key_Enter:
            self.appui_bouton()
        else:
            super().keyPressEvent(qKeyEvent)

    def on_checked(self):
        taille = self.matrixsize()
        if taille == 0:
            pass

        else:
            if self.halfmatrix.isChecked():


                size = int(taille / 2)
                self.matrix.deleteLater()
                self.matrix = QTableWidget()
                self.matrix.setColumnCount(size)
                self.matrix.setRowCount(size)
                self.layout.addWidget(self.matrix,3,20,4)
                self.update()

                self.setLayout(self.layout)

            else:
                self.appui_bouton()

    def process (self):
        
        layout = QHBoxLayout()

        test = self.matrix
        test.setLayout(layout)
        test.show()

因此,为了澄清我的意思:我有一个窗口,在该窗口上您可以获取一些参数(大小,...),当您选择这些参数时,假设您采用matrixsize == 5,则有一个5x5的表是添加到窗口。该表格可以通过拖放系统由其他参数填充(在代码上剪切它们)。 因此,现在我有一个已建好的表,我希望能够通过单击“处理”按钮来仅用该表打开一个新窗口。 所以我不想要动态表,我只想要一个具有相同属性的表(例如,如果矩阵启用了dragonly enable,那么新矩阵应该具有相同的属性)。我想将所有信息保留在单元格中

我希望我已经足够清楚了,这是我第一次问问题(经过多次阅读当然的答案^^) 感谢您的回答和建议!

解决方法

您可以只创建一个没有父级的新QTableWidget(这使其成为顶层窗口),然后显示它:

class Parameters(QWidget):
    # ...
    def process(self):
        rows = self.matrix.rowCount()
        columns = self.matrix.columnCount()
        self.newTable = QTableWidget(rows,columns)
        for row in range(rows):
            for column in range(columns):
                source = self.matrix.item(row,column)
                if source:
                    self.newTable.setItem(row,column,QTableWidgetItem(source))
        self.newTable.show()

请注意,我将新表创建为实例属性。这样可以避免垃圾回收(如果它是一个局部变量)(导致小部件显示并立即消失),但不幸的是,如果再次单击流程按钮并且已经存在一个窗口,则会将其删除并用新窗口“覆盖”。如果要同时拥有更多的过程窗口,可以将它们添加到列表中:

class Parameters(QWidget):
    def __init__(self):
        super(Parameters,self).__init__()
        # ...
        self.processTables = []

    def process(self):
        rows = self.matrix.rowCount()
        columns = self.matrix.columnCount()
        # note that now "newTable" is *local*
        newTable = QTableWidget(rows,columns)
        self.processTables.append(newTable)
        # ...

关于您的代码的一些建议:

  • 每次更改大小时,绝对不需要创建新表;只需在现有的setRowCountsetColumnCount上使用,如果不想保留以前的值,请使用clear();
  • 不要使用两个功能几乎相同的功能(appui_boutonon_checked)并互相调用,而只需使用一个可以同时检查两个方面的功能即可。
  • 不要不必要地调用update():当您更改窗口小部件的属性(或将新的窗口小部件添加到布局中)时,update已经被调用;尽管这不是一个实际问题(Qt在发生实际更新时自动管理 ,并在必要时避免重新绘制),但调用它只会给您的代码添加不必要的噪音;
  • 将小部件添加到网格布局时要格外小心(我指的是on_checked上的代码):如果不需要,请不要使用rowSpan和columnSpan;同样,使用高值是完全没有用的,因为该行中没有其他小部件,并且该布局中实际上只有一列;另外,请勿再次致电setLayout()
  • 如果需要数字值,请使用QSpinBox,而不要使用QLineEdit。

可以很容易地重写用于更新现有表的功能,您应该将按钮复选框都连接到该按钮:

class Parameters(QWidget):
    def __init__(self):
        super(Parameters,self).__init__()
        self.matrixsize = QSpinBox()
        bouton = QPushButton("define matrix_size")
        bouton.clicked.connect(self.appui_bouton)
        self.halfmatrix = QCheckBox()
        self.halfmatrix.toggled.connect(self.appui_bouton)
        # ...

    def appui_bouton(self):
        taille = self.matrixsize.value()
        if self.halfmatrix.isChecked():
            taille //= 2
        if not taille:
            return
        self.matrix.setColumnCount(taille)
        self.matrix.setRowCount(taille)