Qt

Q: про Qt

Граждане, а есть опыт подачи своих патчей в Qt?

Не багфиксов, а расширения функциональности существующих модулей (QDirModel/QFileSystemModel).

Есть смысл куда-то сначала написать (в development?) на предмет "а оно вообще интересно кому-то"?

Я просто опасаюсь потратить на это время - и без результата. Особенно с учетом того, что мы работаем с Qt 5.4, а патчи попадут - если попадут - куда-то в район 5.9

Qt ненависти псто (3)

А вот, значит, еще про Qt.

Допустим, у нас есть QListView (с кастомными элементами, но это в данном случае несущественно). В нем мелко показаны фигульки.

Хотим: при клике на фигульку спрятать QListView и на его месте показать фигульку крупно (в QGraphicsView, хотя это тоже не так и важно).

Первые грабли зарыты в "спрятать-показать". Если запихнуть их, скажем, в один QLayout и делать  QListView->hide(); QGraphicsView->show(), то оно может валится. Не всегда. При некоторых размерах окна. Ну ладно, сначала show/hide, а потом...

Qt MVC: ненависти псто - 2

А вот например Qt. Обычный такой QTableView на две колонки, хочется банального:

  1. Чтобы занимало окошко целиком, даже если строки короткие, иначе там odd/even rows некрасиво.
  2. Чтобы если строки длинные - был бы скроллбар.

Осложняется, правда, тем, что некоторые строки - HTML-ные, то есть их надо руками рендерить. Соответственно, для DisplayRole надо отдавать пустой текст (это я сейчас знаю!), HTML-ку получать другой ролью и рендерить самостоятельно.

И что вы думаете? ДВА ДНЯ. И то, полностью не победил, скроллбар в результате есть всегда. Ну хоть так.

При этом узнал, что SizeHint есть:

  1. В Q...ItemModel::data()
  2. В QTableView::sizeHintForColumn
  3. В QItemDelegate::sizeHint

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

Qt MVC: ненависти псто!

Вот есть такой Qt. А в нем полноценный Model-View: QAbstractItemModel (и потомки), QAbstractItemView (и потомки) ну и "контроллер", то есть делегат.

И вот допустим мы отображаем некий список (произведя его из QListItemModel) в некоем вью (произведя его из QListView). Стандартные средства - хороши, пока их хватает. Иконка, подпись, чекбокс, все есть. Раскраска - стайлшитом.

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

Правда выясняется, что оформление...

Q: Qt, Dynamic OpenGL, OES/ARB extensions

Вот что-то наткнулся и смотрю как на новые ворота.

Преамбула:

  1. Вот есть такой Qt, в нем есть работа с OpenGL
  2. У кого OpenGL нету или кривой - есть библиотека ANGLE, которая эмулирует OpenGL ES2 (или 3) поверх DirectX 9 (или, соответственно, 11).
  3. OpenGL ES от простого отличается, в числе прочего, названиями extensions. Ну, к примеру, GL_OES_get_program_binary у ES/GL_ARB_get_program_binary у обычного.
  4. У Qt 5.4 (под Windows) появилась возможность динамической загрузки имплементации OpenGL. До инициализации QApplication говоришь что хочешь, а дальше
  5. ...

Про QFileSystemModel

А вот возьмем, к примеру, Qt и решим вывести дерево фолдеров (папок, каталогов).

С незапамятных времен в Qt есть QDirModel, которая тянет данные синхронно и, поговаривают, очень от этого тормозит. Не заметил, чтобы очень, но на долю секунды при открытии большого каталога по сети - ну да, есть. Самое плохое в этом то, что оно блокирует UI пока читает каталоги, а пересадить в отдельный (от View) thread, судя по всему, не получится.

А есть новая прекрасная QFileSystemModel,...

Трудовые будни

Сложность окружающего мира продолжает пугать.

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

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

Запускаю инсталлятор, то, се, иконка RD на десктопе, даблкликаю на нее. И НИЧЕГО. Опаньки!

Еще кликаю. Опять ничего. Еще кликаю. Ничего.

Потом, когда я уже пригорюнился, раз и...

FastRawViewer 0.9.1

Первая неделя публичного тестирования FastRawViewer дала ожидаемый результат: обнаружилось некоторое количество мелких багов и мелких пожеланий, которые можно было починить/добавить быстро.

Обновленная версия, 0.9.1, доступна где полагается. Changelog - там же. Впрочем, если вы уже пользователь, то вам встроенная проверка апдейтов скажет о появлении новой версии (в соответствии с настройками, умолчание - проверка раз в неделю).

Помимо исправления ошибок и добавления небольших (но приятных - тем кто их попросил) фичей, достигнуто главное - пополнен список TODO.

Это я к тому все пишу, что вы комментируйте, пишите пожелания. Можно тут. Лучше - на сайте программы, если где-то на форумах других есть обсуждения-пожелания - шлите нам ссылки, будем благодарны.

Ненависти к Qt псто

А вот представим себе такое вот:

  • QGraphicsView и QGraphicsScene
  • Показываем картинку с каким-то увеличением, так что есть скроллбары (или только один)
  • И хотим показать следующую картинку "примерно так же" (в смысле относительного положения окна просмотра относительно всей картинки)
  • И хотим, чтобы когда мы вернулись к предыдущей - позиция сохранялась бы.
Нормальное желание, правда?

Ну вот казалось бы решение:

  • Рассчитать какая (относительная, в координатах 0-1) точка исходной картинки расположена в центре экрана.
  • Рассчитать далее, какая абсолютная точка следующей картинки должна быть в этом самом центре.
  • Дальше - view->centerOn()
Почти работает.

Почти - потому что есть скроллбары, они могут быть, они могут не быть, они могут быть у первой картинки, но не у второй (размеры другие) и наоборот. Скроллбары - меняют центр View (потому что занимают ширину).

И приходится нецензурно закатывать солнце вручную:

  • Если исходно скроллбар есть - запоминаем его относительную позицию (где у нас value() между minimum() и maximum()). Если нет - берем запомненную ранее, когда скроллбар был.
  • Дальше нужно посчитать, будет ли скроллбар при показе следующей (какой размер больше, картинки или viewport()
    • Если не будет, то скроллбар надо явно выключить, потому что если разница в несколько пикселов, то его может включить.
    • Если будет - то явно включить, доверять автоматике нельзя (бывает клево: view ставит скроллбары и зовет resizeEvent(). resizeEvent() знает, что режим у нас fit-to-screen и ресайзит картинку. view - видит что картинка поресайзилась, убирает скроллбары, зовет resizeEvent().....).
  • И если скроллбар будет - то явно ему поставить value (пересчитать из предыдущего относительного)
  • А если не будет - то припрятать относительное value до следующего раза, когда скроллбар появится.
Работает. Можно листать 10 картинок (разного размера и aspect ratio) вперед, потом назад - и вернуться ровно в ту точку/экранную позицию, с которой начинали.

Но, сука, 98 строк кода (считая пробелы). Вместо эдак 8-и, с которыми работает, но примерно.

Q: Qt 5.2 и Retina

Граждане разработчики,

Особенно использующие Qt, вы же тут читаете, я знаю.

Вот есть Qt 5.2 и Маки с ретиной. Надо, значит, чтобы было Щастье.

На самом деле, 99% Щастья есть сходу: если в Info.plist написан NSPrincipalClass, то все стандартные элементы (шрифты, к примеру) рендерятся в ретину и все работает.

Но.

У меня используется свой OpenGL-код, который зовется из QGraphicsScene::drawBackground(). Он, понятно, сходу рисует в четверти окошка в таком случае.

Эксперименты показали, что достаточно...

Про QThread

Несколько дней писал массогабаритный макет многопоточной программы на Qt с использованием QThread

Задача примерно такая: есть пул threads, туда снаружи поступает "задание", нужно выбрать подходящую (по некиим признакам) из простаивающих и скормить задание туда. Threads - долгоживущие, исполняют много заданий.

Имею сказать:

  • Классический способ с переопределением run(), сном там на QWaitCondition и передачей данных через отдельный вызов с блокировкой на QMutex - ужас. Очень жаль, что этот ужас
  • ...

Узок их круг, страшно далеки они от народа

Вот берем Qt 5.1, тащим на Mac OS X 10.7 (так сложилось, это моя девелоперская машина), собираем согласно инструкции.

Далее собираем приложение с этой Qt, деплоим его тоже по инструкции, несем на Mac OS X 10.6 и получаем, получаем... сюрприз:
Неработающее приложение!

То что пишут в mailing lists я приличными словами назвать не могу.

Но только там, в этих рассылках, удается понять, что надо ./configure -no-c++11 и собирать без вебкита (впрочем, у...

Q: Qt MousePressEvent

Я пока не очень опытный Qt хакер, поэтому спрошу.

Вот есть QGraphicsView, у которого есть стандартная функциональность - можно по нажатию левой кнопки мыши скроллить это самое View (setDragMode(QGraphicsView::ScrollHandDrag)).

А теперь, допустим, я хочу делать то же самое не по левой кнопке, а еще по какой-то, скажем по Shift+правая кнопка.

Могу ли я сделать так:

class myView: public QGraphicsView {
  void
...

О синтаксическом сахаре

Есть у меня некий варез и в этом варезе настраивается клавиатурная раскладка (т.е. каждому действию можно сопоставить произвольный клавиатурный аккорд).

В потрохах редактора раскладок содержится примерно такой вот код (по смыслу):

// Инициализация
QKeySequence key; // Текущий shortcut
QPushButton *keybutton = new QPushButton(key.toStrin());
keybutton-
...

Немого кино уже нет, звукового кино еще нет....

Вот есть некая программа, которая активно использует OpenGL.

Используется Qt5 и все было бы хорошо, если бы не моментики:

  • QWidget::showFullScreen() не работает на Mac OS X 10.6
  • Курсор в форме руки - остается таковым и при выносе мыши за окно программы (тоже на Mac, на винде все нормально).
По первому случаю - я засабмитил баг, прямо вот 1-го января. Но он все еще в состоянии Not Evaluated (что неудивительно, если посмотреть на график количества багов в Qt за последние 30 дней). По второму - вроде нашел багрепорт, им как-то занимаются.

Ладно, у меня ничего специфического от Qt5 нету, собираем все то же самое на Qt 4.8.4. Работает (ну, пришлось поменять QOpenGLProgram на QGLProgram и так далее в том же духе, но изменений - мало).

Но:

На операционках, запущенных под VMWare (и Windows и Mac) - валится в QGLFunctions::initializeGLFunctions(), судя по отладчику - GL-контекст в этом месте нехорош, дальше не разбирался).

При этом, Qt5 на этих же виртуальных машинах - работает, возможностей тамошнего OpenGL вполне хватает.

На настоящих железных компьютерах с настоящим OpenGL - версия собранная с 4.8 - работает, а неприятные мне баги на маках - отсутствуют. Фулскрин работает, курсор меняет форму как надо.

Ну и как с ними жить? Баги Qt5 явно быстро не починят. Багу Qt 4.8 - скорее всего тоже не починят. Не, ну я могу gl....() сам порезолвить, но обидно же ж.

Хозяйке на заметку: Qt, OpenGL и PBO

В режиме записок: на этой проблеме впустую потерял дня два минимум, если не больше. Вот, чтобы никогда более, запишу.

Вот есть QGraphicsView, направленный в QGLWidget. Есть еще QGraphicsScene, у которой с помощью drawBackground() рисуем нужное нам (картинку).

Этот самый drawBackground() использует текстуры, одну или много, текстуры залиты через PBO.

Дальше - пытаюсь вывести на эту Scene другие объекты. Ну, как в документации написано, к примеру так:

QLabel *label =
...

Об эффективном использовании современных CPU

Практика вот к этой презентации:

Берем 36Mpix файлик с D800, распаковываем егонный RAW в 16-битный однокомпонентный битмеп, дальше начинаем процессить.

Процессим без "интерполяции", т.е. 4 пикселя исходного байера образуют один выходной пиксель (режим half_size у LibRaw/dcraw). Получаем такие вот времена:

  1. LibRaw::dcraw_process() плюс формирование RGBA-битмепа: 420ms.
  2. Перепишем этот самый dcraw_process() на SSE3, процессить будем в плавучке (с эмуляцией особенностей dcraw), выдаем такой же 8-битный RGBA: 110ms (и более-менее понятно где еще выиграть миллисекунд 20).
  3. Добавим в
  4. ...

Qt+OpenGL benchmarking Q

А вот, я извиняюсь, такой вопрос.

Есть QGrahicsScene (унаследованное от нее) в которой я в drawBackround вывожу OpenGL-ем нечто.

В процессе разбирательств с OpenGL я это нечто имплементировал десятком разных способов и хочу теперь померять, какой из них быстрее.

Но как?

Ну то есть я сделал бенчмарковый вызов, который зумит (еще панорамирует, переключает нужные мне битмепы и т.п., не суть) в таком вот духе:

for(.....){
myview->setZoom(...);
QApplication::processEvents();
}

Но получается вот что:

  • FPS-ов ровно 60 (2000 итераций за 34 секунды), OGLFormat::setSwapInterval(0) не помог.
  • Одно ядро процессора полностью загружено.
  • По профайлеру, загружено оно QWindowsWindow::raise() (~70% по профайлеру), вообще весь прочий код занимает остальные 30% CPU, моего кода вовсе не видно.

Так слона не продать.

Ну то есть понятно, можно в OpenGL-рисовалке рисовать одно и то же 10 (100,1000) раз подряд, но вопрос заключается в том, нет ли более прямого пути, который позволяет Qt-GUI программы побенчмаркать попроще?

Update: если вдруг кому интересно, то проблема решилась глобальным выключением VSync в настройках драйвера (NVidia). FPS-ы сразу сильно выросли, а профайл исполнения стал похож на настоящий.

Про Qt и OpenGL

С помощью профайлера и отладчика узнал прекрасное.

Прекрасное, конечно же, описано в мануале, но кто же их читает:

QGLContext::DefaultBindOption LinearFilteringBindOption | InvertedYBindOption | MipmapBindOption In Qt 4.5 and earlier, bindTexture() would mirror the image and automatically generate mipmaps. This option helps preserve this default behavior.
А я все удивлялся, отчего у меня bindTexture для ~мегапиксельной картинки выполняется миллисекунд 20. Ну конечно, оно переворачивает изображение.

Оторвал. Стало быстрее раз в 10 минимум (на глазок, по профайлеру).

Из другого прекрасного:

  • Если использовать QOpenGLBuffer::bind() и потом, после рисования или заполнения, не сказать ему QOpenGLBuffer::release(), то в QGraphicsView/Scene отваливается отображение элементов, нарисованных стандартным путем (через addItem).
  • Если генерировать структуры руками (glBindTexture/glTexImage2D), но забыть про установку фильтрации, то текстура вовсе не отображается.
Как я уже писал, сколько же есть вещей, которые я предпочел бы не знать.

День прошел не зря.

OpenGL Qs

Сразу предупреждаю: с OpenGL я пытаюсь работать всего неделю (был еще подход к снаряду, но началось лето и я переключился на МонголиеКарелии), поэтому вопросы у меня, вероятно, глупые и вообще про разное.

Вопросов, собственно, три:

1. Допустим, у меня очень простая сцена, два треугольника, образуют прямоугольник, на них натягиваю текстуру (собственно, картинку, которую хочу показать).

Вопрос: есть ли смысл связываться с VBO или 6 пар вызовов glTexCoord2f()/glVertex2f() не будут заметно медленнее? А если прямоугольник не один, а, к примеру, 64 (картинка 8000x8000, а на предельный размер текстуры я заложусь как 1024x1024), будет ли заметный выигрыш, если загнать все в буфер(ы) и дергать рисование меняя только индексы?

Это мне больше для понимания, понятно что как только захочется что-то нарисовать шейдером, так сразу VBO понадобятся.

2. В Qt5 есть (старые) QGL*-объекты, есть новые QOpenGL*.

Кто бы рассказал, в чем разница....

3. Ну и вообще, Qt-шные примеры, что из комплекта, что найденные в сети, какие-то частично безумные. То слишком простые, то вроде простой - а шейдеры там внезапно "#version 330", то - очень хороший пример boxes из поставки - но переусложненный, начинаешь от него куски отпиливать и все разваливается.

Нет ли каких-то Qt-OpenGL tutorials, которые бы с одной стороны были бы "современными" (в смысле используемых Qt-интерфейсов), интересными (не банальный QGLWidget::paintGL()), но и не слишком сложными.

Pages

Subscribe to Qt