Как я могу распечатать QTableWidget, нажав QPushButton

У меня есть интерфейс с двумя вкладками: в первой я прошу пользователя ввести параметры, а во второй я хочу напечатать следующий QTableWidget.

Итак, в основном на первой вкладке у меня есть QPushButton, который я назвал процессом, и обычно, когда я нажимаю на него, я хочу отправить информацию на вторую вкладку.

Прямо сейчас я просто попытался показать новое окно с 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, 0, 0, 1, 1, )
        layout.addWidget(bouton, 0, 1, 1, 1)
        layout.addWidget(QLabel('select half size mode'
                                ), 1, 0, 1, 1)
        layout.addWidget(self.halfmatrix, 1, 1, 1, 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, 0, 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, то новая матрица должна иметь то же самое). Я хочу сохранить всю информацию, содержащуюся в ячейках

Я надеюсь, что я достаточно ясен, потому что я впервые задаю вопросы (после того, как много раз читал некоторые ответы, конечно ^^) спасибо за ваш ответ и совет!


person artemisfowl2    schedule 12.08.2020    source источник
comment
Вы имеете в виду, что в process таблица должна создавать строки и столбцы на основе размера матрицы?   -  person musicamante    schedule 12.08.2020
comment
Нет, я имею в виду: на первой вкладке я могу создать таблицу с нужным вам количеством строк (я утверждаю, что это квадрат). И я могу заполнить его чем угодно. Что я хочу, так это то, что когда я нажимаю «процесс», появляется новое окно с той же таблицей. (это первый шаг, который я хочу пройти, после чего я хотел бы, чтобы нажатие на процесс создавало новое окно с той же таблицей с эволюцией, основанной на функции для данных). Я надеюсь, что я яснее   -  person artemisfowl2    schedule 12.08.2020
comment
первый ответ прислали по ошибке, исправляю, теперь понятнее?   -  person artemisfowl2    schedule 12.08.2020
comment
Ну, это частично зависит от того, что вы собираетесь делать с новой таблицей: должна ли она быть редактируемой? следует ли динамически синхронизировать отредактированные данные с исходной таблицей? Кроме того, ваш пример не воспроизводим, в нем отсутствуют две функции, к которым вы подключаетесь (appui_bouton и on_checked), и нет никаких следов того, как на самом деле применяется размер таблицы. Пожалуйста, отредактируйте вопрос и сделайте его код воспроизводимым, включая все необходимые функции для установки размера таблицы.   -  person musicamante    schedule 12.08.2020
comment
обычно так, это отвечает на проблему, которую вы поднимаете @musicamante   -  person artemisfowl2    schedule 12.08.2020


Ответы (1)


Вы можете просто создать новый 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)
        # ...

Некоторые предложения по вашему коду:

  • нет абсолютно никакой необходимости создавать новую таблицу каждый раз, когда вы хотите изменить ее размер; просто используйте setRowCount и setColumnCount для существующего, и если вы не хотите сохранять предыдущие значения, используйте clear();
  • не используйте две функции, которые делают почти одно и то же (appui_bouton и on_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)
person musicamante    schedule 12.08.2020
comment
большое спасибо за ваш длинный комментарий, я попробую это сегодня и посмотрю, как это работает в моем коде - person artemisfowl2; 19.08.2020