Перейти до основного вмісту

Qt зависання процесу в Windows

Я лінуксоід, і вже натякав на це в інших постах. Але я роблю програми не тільки для використання в середовищі Linux, а й для Windows. Велика частина з того, що я робив первинно була написана саме в Linux, а вже потім перенесена в Windows. Тестуючи програми в обох системах, маю зазначити таку неприємну особливість Windows. При виконанні тривалого процесу, вікно програми зависає. Запускаючи той же самий процес в Linux, принаймні на Ubuntu, такого не трапляється.

Наведу невеличкий приклад. Потрібно витягнути з файлу декілька рядків.

Звичайно, читаючи 20 рядків користувач нічого не помітить. Але я стикався з завданнями, коли обробити потрібно 15 або навіть більше 40 тисяч рядків. І в такому процесі виникає тимчасове "зависання" вікна. Вікно на будь-які дії не відповідає, а іноді Windows просто показує, що програма зависла. Якщо прогресс не відображається, найчастіше, сторонній користувач в диспетчері задач просто "вбиває" процес. Насправді ж процес обробки даних триває в штатному режимі, і результат, незважаючи на тимчасове зависання, буде коректно відображено після виконання всіх дій.

Цікаво, що зависання таке, може і не виникнути. Але якщо в час виконання подібної операції ви вирішили змінити, скажімо, розмір вікна або перемістити його, у вас нічого не вийде.

Є два рішення подібної проблеми. Перша - це розділити операції на потоки, правильне рішення для масштабних, навантажених процесів. У нашому ж випадку, можна обійтися включенням QApplication :: processEvents () в основний цикл и все буде гаразд.



QList list;
for (int x = 0; x < list.count(); x++) {
   ...
   ui.progressBar->setValue(qFloor((x + 1) * 100 / list.count()));
   QApplication::processEvents();
}



Якщо ви уважно дивились відео, то мабуть помітили, що коли процесс не відображається він проходить скоріше ;)

Коментарі

Популярні дописи з цього блогу

QString в HEX и обратно

Спочатку з QString робимо QByteArray. Зауважимо, якщо у вас по тексту тільки латинські букви цілком підійде варіант з .toUtf8(). Якщо ж присутня і кирилиця - обов'язково використовуємо .toLocal8Bit(). QString strA = "Some text"; QByteArray bA = strA.toLocal8Bit().toHex(); Перетворення QByteArray в початковий текст має такий вигляд: QString strB = QString::fromLocal8Bit(QByteArray::fromHex(bA))); Цікаво, що якщо ми для зберігання записали отриманий Нех куди-небудь, наприклад, в файл або базу даних у вигляді текстового рядка, то для зворотного перетворення цей рядок потрібно додатково перетворити в QByteArray. QString strA2 = QString::fromUtf8(bA); QByteArray bB = strA2.toUtf8(); QString strB = QString::fromLocal8Bit(QByteArray::fromHex(bB)));

Qt Округлення до певного розряду

Округлення - тривіальна задача в математиці, але в Qt немає функції округлення до певного розряду. Проте в QtMath є такі функції як qFloor (qreal) і QCeil (qreal), в результаті яких int. А також можна використовуючи round (double), отримати double. Дуже швидко я знайшов ось цей ресурс звідки взяв вихідну формулу. Вона без сумніву працює, але дає результати, які не відповідаю моїм очікуванням: toRound(187.156, 2); //187.15 toRound(187.156, 1); //187.1 toRound(187.156, 0); //187 toRound(187.156, -1); //180 toRound(187.156, -2); //100 Після невеликої корекції самої функції, її підсумковий варіант виглядає так: double wcsv::toRound(double val, int r) {   double outpValue;   double tempVal;   tempVal=val*pow(10,r);   if (double(int(tempVal))+0.5==tempVal){     int(tempVal)%2 == 0       ? outpValue=double(qFloor(tempVal))/pow(10,r)       :outpValue=d...

CSV в QTableWidget

Питання виникло в зв'язку з виниклою необхідністю прочитати .xls файл в Linux'і. Я так думаю у більшості користувачів Linux, є якийсь небудь офісний пакет, такий як OpenOffice або LibreOffice або щось там ще, за допомогою якого можна легко конвертувати .xls в .сsv. А .сsv - це текст, який можна читати в будь-якій системі. Пропоную читати файл у QTableWidget. Зберемо простеньку програму. Файл file_csv.csv виглядає так:   На форму покладемо QTableWidget, QListWidget, QPushButton. void MainWindow::readFile(){     QFile file("file_csv.csv"); //файл (треба буде зробити діалог)     QStringList listA; //лист в який запишемо данні     int row = 0; //кількість рядків у майбутній таблиці (ми ж не знаємо скільки їх там ;)     if (file.open(QIODevice::ReadOnly)){         while (!file.atEnd()){             QString line = file.r...