Russian Qt Forum
Ноябрь 25, 2024, 20:54 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Утечка памяти  (Прочитано 9845 раз)
Spark
Гость
« : Июль 16, 2013, 15:13 »

Функция перебора вертикального списка имен для передачи пунктов списка иной функции (слайдшоу).
Код
C++ (Qt)
void MainWindow::slideshowOn(bool on)
{
   if(!on)return;
   slideShowQuit = false;
   slideShowStop = false;
 
   QString importPath;
   if( cfg.contentExportPath.isEmpty() )
       importPath = QDir::homePath();
   else
   {
       importPath = QDir::fromNativeSeparators( cfg.contentExportPath );
       if( !QDir( importPath ).exists() )
           importPath = QDir::homePath();
   }
 
   QString fileName = QFileDialog::getOpenFileName( this, tr( "Slideshow content from file" ),
                                                    importPath,
                                                    tr( "Text files (*.txt);;All files (*.*)" ) );
   if( fileName.size() == 0)
   {
       slideshowButton->setChecked(false);
       return;
   }
 
   QFileInfo fileInfo( fileName );
   QString contentName = fileInfo.baseName();
   QFile file( fileName );
   int n(0);
 
 
   // Count slides
   if ( file.open( QFile::ReadOnly ) )
   {
 
       char buf[1024];
       qint64 lineLength;
       forever
       {
           lineLength = file.readLine(buf, sizeof(buf));
           if (lineLength > 0)
           {
               ++n;
           }
           else if (lineLength == -1)
           {
               break;
           }
       }
       file.close();
   }
 
 
       if ( file.open( QFile::ReadOnly | QIODevice::Text ) )
 
       {
 
 
       QTextStream fileStream( & file );
       QString itemStr, trimmedStr;
 
 
       QString str;
       str.setNum(n);
 
 
       slidePopup->setWindowTitle( contentName + "/" + str );
 
// slide Show
       do
       {
 
// Pause
           do
           {
               QEventLoop loop;
               QTimer::singleShot(0, &loop, SLOT(quit()));
               loop.exec();
           } while(slideShowStop);
 
 
           itemStr = fileStream.readLine();
           if( fileStream.status() >= QTextStream::ReadCorruptData )
               break;
 
           trimmedStr = itemStr.trimmed();
           if( trimmedStr.isEmpty() )
               continue;
 
           if(slideshowPopup->isChecked())slidePopup->slideTranslationFor( trimmedStr );
           if(slideshowGrand->isChecked())showTranslationFor( trimmedStr );
 
           QEventLoop loop3;
           QTimer::singleShot(cfg.preferences.slideShowTimer, &loop3, SLOT(quit()));
           loop3.exec();
 
           if(slideShowQuit)break;
 
       } while( !fileStream.atEnd() );
 
       file.close();
       }
}
Запускаю слайдошоу с основного окна mainwindow.cc. Все функционирует как надо и при маленьком и при большом списке. Никакой утечки не наблюдается. Если окно слайдов предварительно закрыть, то сама программа закрывается благополучно. Если окно слайдшоу включено, то при маленьком списке программа закрывается нормально.
Но если список велик (например 100 тысяч), то при включенном окне слайдшоу не получается нормально закрыть программу. Висит. А в диспетчере задач наблюдается быстрое увеличение объема памяти для программы в момент закрытия.
В чем может быть проблема?
Записан
Spark
Гость
« Ответ #1 : Июль 17, 2013, 09:31 »

Понимаю, что необходимо предварительно закрыть слайдшоу.

Если выхожу корректно, отсылая предварительно сигнал на слот(нажимаю кнопку "стоп слайды" в основном окне):
Код
C++ (Qt)
void MainWindow::slideshowOff( bool )
{
   slideShowQuit = true;
}
После этого закрытие всей программы благополучное.

В mainwindow.cc прописал связь:
Код
C++ (Qt)
 connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(slideshowOff( bool )));
Не срабатывает. Если слайдшоу еще работает, программа не может выйти корректно.
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #2 : Июль 17, 2013, 11:48 »

у слота не может быть параметров больше, чем у сигнала (только если они не по умолчанию). непонятно зачем ты вообще туда этот bool прилепил.
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Spark
Гость
« Ответ #3 : Июль 17, 2013, 12:09 »

у слота не может быть параметров больше, чем у сигнала (только если они не по умолчанию). непонятно зачем ты вообще туда этот bool прилепил.
Да вроде я это понимаю. Экспериментировал.

Но функция, останавливающая void MainWindow::slideshowOn(bool on), перестает работать в таком виде :
Код
C++ (Qt)
void MainWindow::slideshowOff()
{
   slideShowQuit = true;
}
Как я это реализовал видно здесь http://www.prog.org.ru/index.php?topic=25276.msg180591#msg180591
А ка бы вы остановили slideshowOn(bool on)?

Честно говоря отчаялся правильно реализовать. Видимо придется оставить как есть (работает однако) до осознания данного момента.
« Последнее редактирование: Июль 17, 2013, 12:32 от Spark » Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #4 : Июль 17, 2013, 12:34 »

я бы QEventLoop loop3 поместил в класс и останавливал бы ее перед установкой флажка
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #5 : Июль 17, 2013, 12:39 »

А почему вместо организации задержки, не менять картинки по сигналу таймера?
Записан
Spark
Гость
« Ответ #6 : Июль 17, 2013, 12:46 »

Т.е. пока, что так. Есть кнопка в главном окне, нажимая на которую испускаем сигнал:
Код
C++ (Qt)
 connect( slideshowButton, SIGNAL( toggled( bool ) ),
          this, SLOT( slideshowOn( bool ) ) );

Срабатывает слот:
Код
C++ (Qt)
void MainWindow::slideshowOff( bool )
{
   slideShowQuit = true;
}

Однако, функция слайдшоу slideshowOn(bool on) срабатывает и заряжает:
Код
C++ (Qt)
slideShowQuit = false;

И теперь при нажатие кнопки слайдшоу, слот снова срабатывает, но в этот раз останавливает цикл показа слайдов. И вот в этот момент я могу спокойно выключить и главное окно. Но если предварительно не выключить слайдшоу, то - траблы.
Записан
Spark
Гость
« Ответ #7 : Июль 17, 2013, 12:54 »

А почему вместо организации задержки, не менять картинки по сигналу таймера?
Т.е вы имеете ввиду вместо:
Код
C++ (Qt)
           QEventLoop loop3;
           QTimer::singleShot(cfg.preferences.slideShowTimer, &loop3, SLOT(quit()));
           loop3.exec();
поставить:
QTest::Sleep (5000);
У меня непутевого не сработало. Компилятор ругается: ошибка: undefined reference to `QTest::qSleep(int)'
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #8 : Июль 17, 2013, 12:56 »

QT += testlib
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #9 : Июль 17, 2013, 12:57 »

У меня непутевого не сработало. Компилятор ругается: ошибка: undefined reference to `QTest::qSleep(int)'
Нет, я предлагаю использовать QTimer, который будет генерировать сигнал с нужным интервалом, по которому будут изменяться картинки.
Записан
Spark
Гость
« Ответ #10 : Июль 17, 2013, 13:02 »

Спасибо.
Сейчас буду пытаться понять ваши советы и экспериментировать Улыбающийся. Все таки каждый шаг осознания дается с боем.
Записан
Spark
Гость
« Ответ #11 : Июль 17, 2013, 13:03 »

У меня непутевого не сработало. Компилятор ругается: ошибка: undefined reference to `QTest::qSleep(int)'
Нет, я предлагаю использовать QTimer, который будет генерировать сигнал с нужным интервалом, по которому будут изменяться картинки.
По этому поводу скажите только одно. Это может решить текущую проблему? Или в противном случае изучение этого метода лучше отложить?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #12 : Июль 17, 2013, 13:19 »

По этому поводу скажите только одно. Это может решить текущую проблему? Или в противном случае изучение этого метода лучше отложить?
Это другой подход (на мой взгляд более правильный) к решению вашей задачи.
Записан
Spark
Гость
« Ответ #13 : Июль 17, 2013, 14:00 »

Попутно опубликую второй момент, который хотелось бы решить.
Думаю ясно как реализован запуск и пауза слайдшоу:
http://www.prog.org.ru/index.php?topic=25276.msg180591#msg180591
Но такой подход не очень эргономичен:
- Нажатие кнопки вызывает выбор текстового списка слайдшоу.
- Второе нажатие (отжимает кнопку) выключает слайдшоу.
- Пауза работает с контекстного меню.

А хотелось бы, что бы второе нажатие вызывало паузу. В общем то это не сложно. Сложно продолжить слайдшоу после паузы, нажав на эту же кнопку. Как ни пытался не получилось.
Может подскажете не сложный способ или направите в нужное русло?
Записан
Kurles
Бывалый
*****
Offline Offline

Сообщений: 480



Просмотр профиля
« Ответ #14 : Июль 17, 2013, 15:11 »

А хотелось бы, что бы второе нажатие вызывало паузу. В общем то это не сложно. Сложно продолжить слайдшоу после паузы, нажав на эту же кнопку. Как ни пытался не получилось.
Может подскажете не сложный способ или направите в нужное русло?
Тему не читай - сразу отвечай: что мешает где нибудь хранить состояние кнопки, да хотя бы в свойствах (bool QObject::setProperty ( const char * name, const QVariant & value ) и QVariant QObject::property ( const char * name ) const)?
Записан

Код
C++ (Qt)
while(!asleep()) sheep++;
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.312 секунд. Запросов: 23.