Как исправить QTableWidget setText / setCellWidget, вызывающий сбой при загрузке QSettings - PullRequest
0 голосов
/ 07 февраля 2019

Здравствуйте, я использую QTableWidget и, по сути, имею такой код, что первый столбец позволяет динамически увеличивать / уменьшать таблицу.Первая ячейка последней заполненной строки будет иметь кнопку «Плюс» для добавления новой строки, которую можно редактировать, а кнопка «Минус» удалит строку соответствующей кнопки.Например, если я нажму кнопку «Плюс» 5 раз, она будет в 6-й строке, а все предыдущие 5 строк будут иметь кнопки «Минус» для удаления своей строки.Если в строке ячейки есть кнопка «Минус», она подразумевается редактируемой, в противном случае - нет.Тем не менее, я позволю таблице иметь количество строк по умолчанию, так что она никогда не сможет визуально сжаться меньше 5, например, даже если она технически «пуста».Чтобы редактировать строку, вам нужно нажать кнопку «Плюс», которая проверит, нужно ли нам вставлять новую строку, например, если у нас 5 строк, а базовый размер строки равен 5, тогда нам нужна новая строка и заполнитьиндекс каждого столбца новой строки.

Основная причина этой таблицы состоит в том, чтобы читать и записывать информацию таблицы в QSettings и иметь возможность импортировать ранее экспортированную информацию в те же ячейки и, по существу, восстанавливать состояние таблицы в том виде, в котором оно появилось последним.Однако при чтении из QSettings таблица вылетает после того, как все ячейки заполнены информацией правильно, и я могу сказать, что они правильно заполнены, потому что отладчик замораживает графический интерфейс, и я могу визуально видеть и qDebug(), как далеко вцикл массива QSettings, до которого я добрался до seg-faulting.

Теперь, когда я делаю все вручную, например, нажимаю кнопку «Плюс», все в порядке, и программа работает, как и ожидалось.

//newRowCount is assumed to be the amount of rows with Minus Buttons currently, only creates a new row if the table needs to expand
void TableTest::enableNewRow(){
    newRowCount++;
    if(newRowCount > table->rowCount()){
        table->insertRow(table->rowCount());
        for(int i = 0; i < table->columnSize(); ++i){
            QTableWidgetItem* item = new QTableWidgetItem;
            item->setFlags(item->flags() ^ Qt::ItemisEditable);
            table->setItem(newRowCount, i, item);
            //Code to set the previous column's item (newRowCount--) to have an Qt::ItemisEditable flag set to true
            ...
        }
    }
        //Some button setup to make Plus button and create a new Minus button connect and do their jobs and move the Plus button down into the newly inserted row
        ...
}
void MainWindow::importFile(){
    int settingRows = settings->beginReadArray("Groups");
    for(int i = 0; i < settingRows; ++i){
        settings->setArrayIndex(i);
        //Will only add a new row if needed, check inside above function and all row items will be allocated if made
        table->enableRow();
        for(int j = 1; j < table->columnCount(); ++j){
            table->item(i, j)->setText("testing");
        }
    }
}

And the program crashes with the following stack trace:
1  QWidget::show()
2  QAbstractItemView::updateEditorGeometries()
3  QAbstractItemView::updateGeometries()
4  QTableView::updateGeometries()
5  QTableView::timerEvent(QTimerEvent *)
6  QObject::event(QEvent *)
7  QWidget::event(QEvent *)
8  QFrame::event(QEvent* )
9  QAbstractScrollArea::event(QEvent* )
10 QAbstractItemView::event(QEvent* )
11-21 ... Not useful information about any of the code
22 QCoreApplication::exec()
23 main

Однако, это весь байт-код, и я не могу проверить, какая строка вызывает сбой кода в какой-либо из трассировок, используя отладчик.Что я не понимаю, так это то, что тот же процесс для ручного нажатия кнопки «Плюс» завершается (я подключаю событие нажатия кнопки «Плюс» к функции enableRow()), и когда я программно вызываю enableRow() из QSettingsзацикливание на importFile() произойдет сбой после прохождения всех элементов.

На заметку: установка базового размера таблицы в соответствии с размером массива QSettings, из которого я читаю (т. Е. Если я хочу 10 строк, просто установите 10 строк для начала, прежде чем устанавливать тексты элементов,работать правильно), однако, я хочу, чтобы базовый размер таблицы при создании был чем-то вроде 5. Кажется, что как только цикл выходит за пределы числа строк, которое я указал в конструкторе, тогда программа завершится сбоем, но, скажем, не по индексу6, но только после того, как он полностью перебрал таблицу.Он не падает ни на одной строке, такой как QTableWidgetItem::setText или QTableWidget::setCellWidget().Я немного сбит с толку и задаюсь вопросом, не заполняет ли таблица слишком быстро для QTableWidget::timerEvent в строке трассировки стека 5. Ничто из того, что я делаю в цикле, ничем не отличается от того, что я делаю при обычной работе с таблицей.

1 Ответ

0 голосов
/ 07 февраля 2019

Оказывается, ошибка была в том, что я устанавливал QTableWIdgetItem на одну строку раньше, чем должен был быть.Я не уверен, почему таблица могла бы повторяться до конца цикла QSettings перед сбоем, но это было по существу ошибкой.Я не совсем уверен, почему трассировка стека была такой загадочной.

в моей функции enableRow () я фактически вывел выше из памяти правильную логику, которая отличалась в логике моего кода на 1 индекс ранее для значения строки.Почему код не вылетал при обычном использовании с кнопками, слоты которых вызывали ту же функцию, что и import(), кажется, сбивает с толку меня, возможно, случай неопределенного поведения.

...