Qt

В этом разделе описаны разные трюки и HowTo применительно к использованию библиотеки Qt.

Ошибка встраивания манифеста в исполняемый файл

В последнее время при сборке Qt-проектов компилятором от Visual Studio стал периодически видеть такую ошибку:

mt.exe : general error c101008d: Failed to write the updated manifest to the resource of file ...

Меня это начало напрягать и я решил разобраться в причине. Оказалось, что директория, в которую компилятором складываются все промежуточные файлы (в том числе и манифест), почему-то имеет атрибут Read Only. После отключения у папки этого атрибута ошибка пропала.

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

Отзовик - пишите отзывы и получайте деньги!

Связка QComboBox и QTreeView

6 апреля 2017 (13:32:59)

В одном из выпадающих списков (QComboBox) мне потребовалось отобразить некую древовидную структуру элементов. По сути, всё сводится к установке QTreeView в качестве выпадающего списка для QComboBox. Задача тривиальная: создаём модель (я взял стандартную QStandardItemModel), создаём вид (QTreeView), связываем модель с видом и устанавливаем их в качестве модели и вида для нужного экземпляра QComboBox. Тут ничего сложного нет.

Проблемы начались, когда мне потребовалось программно установить текущий элемент в QComboBox. Решение нашлось, хотя и не сразу и не совсем прямое:

/* Определяем индекс в модели, который нужно сделать текущим */
QModelIndex index = findIndex();

/* Устанавливаем текущий элемент у view */
view->setCurrentIndex( index );

/* Устанавливаем текущий элемент в QComboBox */
myComboBox->setRootModelIndex( index.parent() );
myComboBox->setCurrentIndex( index.row() );
myComboBox->setRootModelIndex( QModelIndex() );

Отзовик - пишите отзывы и получайте деньги!

Источники данных ODBC для Qt-программ под Windows (64 бит)

23 марта 2017 (18:17:52)

Написав программу, взаимодействующую с базой данных посредством источников данных ODBC, я столкнулся с неприятной проблемой: 32-х битные программы, написанные на Qt и запущенные под 64-х битными операционными системами Windows, не видят источников данных, созданных штатным способом, т.е. через диалог, вызванный из панели управления. Решение нашлось на одном из зарубежных программистских форумах. Приведу его тут, чтобы не забыть самому и, быть может, оказаться полезным кому-нибудь ещё. Итак, создайте свои ODBC-источники через следующую программу:

C:/Windows/SysWOW64/odbcad32.exe

После запуска этой программы на экране вы увидите диалог, абсолютно идентичный классическому диалогу создания ODBC-источников, однако источники, созданные этим способом, будут видны 32-х битным Qt-программам под 64-х битными Windows.

Отзовик - пишите отзывы и получайте деньги!

Иконка для приложения средствами Qt

Установить иконку для уже запущенного приложения проще простого:

QApplication::setWindowIcon( QIcon( "myapp.ico" ) );

Но вот беда - в проводнике Windows у исполняемого файла будет стандартная иконка средней паршивости. Исправим это. Для этого надо создать файл myapp.rc следующего содержания:

IDI_ICON1 ICON DISCARDABLE "./myapp.ico"

Затем в проектный файл (.pro) добавляем строчку:

win32: RC_FILE = myapp.rc

Теперь после сборки приложения у исполняемого файла будет красивая иконка.

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

Отзовик - пишите отзывы и получайте деньги!

Кодировки INI-файлов в Qt

8 июля 2016 (15:19:09)

В программах часто требуется читать и писать информацию при помощи INI-файлов. В библиотеке Qt это делается при помощи класса QSettings:

QSettings in( "input.ini", QSettings::IniFormat );

Пока данные в этих файлах содержат строчки в латинице - всё хорошо. Однако, как только в данных появляется кириллица, то метод value() класса QSettings может вернуть абракадабру.

Чтобы этого избежать, необходимо настроить кодек, который будет использоваться для чтения и записи данных из INI-файла:

in.setIniCodec( "Windows-1251" );

Теперь данные в кодировке Windows-1251 будут прочитаны корректно.

Отзовик - пишите отзывы и получайте деньги!

Своя функция задержки в Qt

12 апреля 2016 (14:37:49)

Довольно часто в программах, написанных на Qt, бывает необходимо осуществить задержку в куске кода. Если вы пишете класс-наследник QThread, то вам повезло, поскольку в вашем распоряжении есть функция-член класса QThread msleep(). Но что делать, если задержку надо вставить в методе класса, который не наследуется от QThread? Или в функции, которая вообще не является членом класса?

Для решения этой задачи я обычно использую вот такую простую функцию:

inline void qt_msleep( int ms )
{
  QSemaphore s( 0 );
  if( ms > 0 )
    s.tryAcquire( 1, ms );
}

Здесь задержка организована посредством попытки захватить семафор в течение заданного времени (в миллисекундах).

Отзовик - пишите отзывы и получайте деньги!