У меня есть программа, в которой я теперь сохраняю большие, 18 мегапикселей или меньше изображений на диск. По пути я конвертирую их в QImage, показываю QImage в подклассе QDialog, а затем предлагаю пользователю их сохранить.Как проверить, что QImage :: save() закончил запись на диск?
Я хотел, чтобы у пользователя был какой-то индикатор прогресса, поэтому я рассуждал о том, что лучший способ достичь этого - создать QThread, сохранить изображение с рабочим в потоке и затем испустить сигнал вернитесь в GUI, чтобы объявить, что сохранение закончено. Я использую этот метод, чтобы показать индикатор выполнения пользователю во время процесса сохранения.
Рассмотрим простой класс уборщица здесь:
class Worker : public QObject
{
Q_OBJECT
public slots:
void doWork(const QImage &image, const QString &file) {
if(image.save(file, "PNG", 100))
emit resultReady();
else
{
// handle error
return;
}
}
signals:
void resultReady();
};
Моя проблема заключается в том, что изображение :: сохранить() функция возвращает true
часто задолго до того, как изображение фактически закончил писать на диск. С этой текущей строкой кода на моем 5600 HDD сигнал resultReady()
запускается примерно через 6 секунд после нажатия пользователем кнопки, и, таким образом, мои обновления графического интерфейса, чтобы показать, что изображение закончило сохранение.
Однако QImage, кажется, занимает от 7 до секунд до 30 секунд, чтобы закончить запись на диск. В течение этого времени пользователь мог бы закончить приложение, что приводит к неполному изображению на диске, поскольку поток считает себя выполненным. Возможно, еще хуже, пользователь мог бы взять несколько других изображений, которые начинают усугублять длительность сохраненных изображений.
Есть ли способ определить, когда приложение Qt закончило писать QImage на жесткий диск?
Вы правы. Теперь я понимаю, что моя проблема заключается в том, что функции, которые используются для включения и отключения содержимого графического интерфейса, эффективно небезопасны из-за общих объектов потоковой передачи. Я тестировал процесс сохранения изображений, быстро запуская кнопку сохранения всякий раз, когда она была доступна. Я думаю, что, делая это, я имел шанс создать несколько потоков, которые будут сохраняться на жестком диске примерно одновременно, вызывая перегрузку. Затем один из них закончит, и я закрою программу, пока другой поток все еще находится в процессе сохранения. Что-то в этом роде. – Ketta
Как в стороне, в вашем примере для CountDownLatch, который вы связали, вы хотите использовать фигурные скобки по всему коду в определениях Locker? Я попытался посмотреть на этот пример и, похоже, вы хотели использовать круглые скобки для различных функций, верно? Я еще не могу комментировать другие темы или я бы разместил это там. – Ketta
@ Ketta Код, который я опубликовал, был скомпилирован и протестирован. Так может выглядеть современный C++. C++ 98/03 используется для перегрузки тех же круглых скобок, что означает слишком много вещей: группировка выражений, вызов функции/метода и вызов конструктора. В C++ 11 вызов конструктора получает собственный синтаксис с '{}' фигурными скобками. Это позволяет легко отличать вызовы методов и другие выражения от инициализации объекта. –