#c #linux #qt #dialog #qt5
Вопрос:
У меня есть пользовательский QDialog с кнопкой «Сохранить», которая должна запрашивать у пользователя QFileDialog и сохранять содержимое виджета таблицы в файл, но сохранять диалоговое окно открытым.
Это функция, которая открывает диалоговое окно и сохраняет данные:
bool ResultsDialog::saveData()
{
QString outfile = QFileDialog::getSaveFileName(this, tr("Save results"), tr(""), tr("CSV Files (*.csv)") );
if (outfile.isNull() || outfile.isEmpty() )
return false;
if (!CSVIO::write_to_csv(*ui->tableWidget, outfile) )
{
QMessageBox::critical(this, "Failed to save...", QString("Could not save file: %1").arg(outfile) );
return false;
}
return true;
}
Это код для слота кнопки Сохранить:
void ResultsDialog::on_saveButton_clicked()
{
if (saveData() )
{
saved = true;
}
}
РЕДАКТИРОВАТЬ: Это код, который создает и открывает каталог результатов:
void MainWindow::displayResults()
{
ResultsDialog *resultsDialog = new ResultsDialog(this);
resultsDialog->setWindowTitle(windowTitle() );
resultsDialog->setWindowIcon(windowIcon() );
connect(resultsDialog, amp;ResultsDialog::finished, this, amp;MainWindow::close);
resultsDialog->fill(playlistTable, notes);
resultsDialog->setModal(true);
resultsDialog->open();
this->hide();
}
Проблема в том, что, как только QFileDialog закрывается, мой QDialog закрывается вместе с ним, и на консоли выводится следующее сообщение:
в Qt.qpa по.xcb: QXcbConnection: XCB ошибки: 3 (BadWindow), последовательность: 13049, идентификатора ресурса: 25205189, майор код: 40 (TranslateCoords), незначительные код: 0
11:59:01: /главная/пользователь user1/рабочее пространство/строительство-приложение-рабочий стол-отладка/приложение завершился с кодом 0
Обратите внимание, что главное окно, которое является родительским для моего пользовательского диалога, скрыто. Когда он не скрыт, эта проблема исчезает, но это не вариант, так как я хочу, чтобы главное окно было скрыто.
Я использую Qt 5.15 в Debian Bullseye.
Комментарии:
1. Просто проверяю, хорошо ли я понимаю: значит, если ваше главное окно не скрыто, то ваш каталог результатов автоматически не закрывается после закрытия QFileDialog?
2. Это правильно. Я добавляю код, который открывает каталог результатов.
Ответ №1:
Вы подключаете завершение основного окна к сигналу, который отправляется, пока ResultsDialog все еще обрабатывается. ResultsDialog имеет главное окно в качестве родителя, поэтому родитель (и его потомки!!) уничтожаются, пока ребенок еще бежит. Из этой конструкции не выйдет ничего хорошего.
Редактировать: Сообщение об ошибке, которое вы видите, не является источником проблемы, а просто указывает на то, что окно было внезапно закрыто. И это именно то, что вы описываете.
Редактировать 2: Смотрите раздел комментариев для обходного пути (передача 0 в качестве родителя в диалоговом окне) и некоторых предположений о том, почему обходной путь работает.
Комментарии:
1. Это может быть проблемой, а может и не быть, но проблема не в этом. У меня не было никаких других проблем с этой конструкцией. Предполагается, что приложение завершит работу, когда журнал результатов будет закрыт. Есть что — то, что делает QFileDialog, что заставляет ResultsDialog закрываться раньше, чем это должно быть, и я не могу выяснить, что это такое-вот в чем проблема.
2. Я упустил тот момент, что было закрыто намеренно и что действительно закрылось волшебным образом. Здесь происходит что-то непонятное: можете ли вы открыть каталог результатов с помощью exex() вместо open (), чтобы сделать его подходящим модальным диалогом приложения (для этого вам, возможно, придется инвертировать вызов hide и exec)? Что произойдет, если вы нарушите родительскую иерархию и передадите 0 в конструкторе ResultsDialog и GetSaveFileName?
3. Я мог бы поклясться, что пытался передать 0 в качестве родителя для ResultsDialog, но, похоже, теперь это сработало. По крайней мере, в Linux — так как приложение также должно работать на Mac и Windows, я тоже протестирую на них. Передача 0 в GetSaveFileName не оказала никакого эффекта. Изменение между exec() и open() также не имеет значения.
4. Я предполагаю, что какой-то внутренний пытается получить доступ к размеру панели инструментов главного окна, который, вероятно, дает 0, когда скрыт, и что какой-то элемент пытается использовать этот 0 в делении. Цепочка доступа к скрытой панели прерывается, передавая 0.
5. Это приятно знать… Я заметил интересное поведение с этой ошибкой: я отключил отклонение() для ResultsDialog для отображения QMessageBox если пользователь попытается закрыть, не сохраняя данные, и при QFileDialog отменен, он запускает эту функцию и окно сообщения приложение сохраняет жив — хотя приложение все еще умирает, когда сообщение, окно закрывается, даже если
Go Back
кнопка была нажата. Я могу подтвердить, что этот обходной путь работает на macOS и Windows, поэтому я приму ваш ответ.