воскресенье, 10 февраля 2019 г.

MS Visual Studio и mocinclude.tmp

Если в вашем проекте больше 40 путей include, которые описаны в INCLUDEPATH, то Qt создает временный файл mocinclude.tmp, в который включает все описанные пути.
Проблема в том, что студия не совсем корректно обрабатывает этот файл. Выражается это в том, что при каждой сборке студия начинает полностью пересобирать проект вместо того, чтобы пересобрать только измененные файлы.
Чтобы не допустить создания mocinclude.tmp надо изменить в Qt файл

d:\qt\mkspecs\features\moc.prf

изменив строчку
win32:count($$list($$INCLUDEPATH), 40, >) {
на 
win32:count($$list($$INCLUDEPATH), 100, >) {

Таким образом мы просто увеличили количество путей с 40 до 100.

среда, 6 февраля 2019 г.

Qt Installer: удаление по маске

Qt Installer не умеет удалять файлы по маске.
Нельзя просто так взять и написать
 component.addOperation("Execute", "rm", "-f", "files*");
Это не сработает. Это обходится вызовом командного интерпретатора

Для Windows
      component.addOperation("Execute", "cmd.exe", "/C", "del", "files*.*");

Для Linux
      component.addOperation("Execute", "bash", "-c", "rm -f files*");
Последний параметр для Linux надо писать целиком, не разделяя на части. В этом случае Qt Installer при вызове обернет команду кавычками и результат будет как если бы вы вызвали команду
bash -c "rm -f files*" 

вторник, 5 февраля 2019 г.

Qt Installer: replace

Qt Installer использует скриптовый язык ECMAScript (http://doc.qt.io/qt-5/ecmascript.html)
По структуре он схож с JavaScript, но полностью они не пересекаются.
Но решения можно искать и по JavaScript.
Например, функция replace меняет только первое вхождение в строку.
var str = "bla-bla-bla";
str.replace("bla", "vobla");
Получим vobla-bla-bla.
Чтобы заменить все вхождения, надо использовать регулярку.
str.replace(/bla/g, "vobla");

четверг, 21 апреля 2016 г.

Снова по прокрутке большой БД

Возвращаюсь к теме просмотра большой БД в виде одной большой таблицы QTableView.
Ранее я писал про извращения с наследником QTableView, теперь будем делать это каноничнее.
Итак, есть большая БД, на 100 килострок минимум. Какая БД неважно, FireBird, SQLite и т.п.

Первое, что надо сделать это определить модель.
class QueryModel : public QAbstractTableModel
и определить в ней rowCount(). rowCount() определяется так:
"SELECT COUNT(ID) FROM TABLE"

Затем в классе определяем экземпляр QSqlQuery query_, которому говорим SELECT * FROM TABLE, условно.

Далее определяем data()
QVariant QueryModel::data(const QModelIndex & index, int role) const
{
   if (role == Qt::DisplayRole)
   {
      if (query_->seek(index.row()))
      {
         const QSqlRecord & rec = query_->record();
         QVariant val = rec.value(index.column());
         QString str = val.toString();
         return str;
      }
   }
}

Всё. Этого достаточно чтобы иметь нормально прокручиваемую таблицу.
Небольшое дополнение, не нужно вызывать функции resizeColumnsToContents() и resizeRowsToContents(), это вызовет метод data() для всех строк и получите тормоза.

вторник, 13 января 2015 г.

Порядок #include

Правило подключения имхо очень простое, его не сложно запомнить и не сложно ему следовать:
в файле MyClass.cpp
#include <vector> (1) сначала подключаются файлы стандартной библиотеки
#include <boost/smart_ptr.hpp> (2) затем подключатся файлы 3rd-party библиотек, 
                                   объекты и функции которых Вы используете в
                                   своём коде
#include <MyInclude/Helpers.h> (3) свои внутренние заголовочные файлы
#include <MyClass.h> (3) свой заголовочный файл, реализацию для которого мы пишем

среда, 10 сентября 2014 г.

Тестовое задание в компанию IVIDEON

Фонарь (тестовое задание)

Требуется написать управляемый по сети фонарь. Команды управления фонарь
принимает от сервера фонаря. Предполагается, что реализация сервера уже
существует (однако недоступен вам в процессе разработки клиента фонаря).

Фонарь и сервер общаются по Протоколу Управления Фонарем, работающему поверх
соединения TCP.

Протокол Управления Фонарем (ПУФ) устроен следующим образом. Для изменения
состояния фонаря сервер передает ему команду управления. Все команды
кодируются в виде TLV (http://en.wikipedia.org/wiki/Type-length-value), при
этом поле type имеет размер 1 байт, поле length — 2 байта и поле value —
length байт. Все данные передаются по сети в Big Endian.

ПУФ версии 1 описывает три команды:
● ON (включить фонарь): type = 0x12, length = 0
● OFF (выключить фонарь): type = 0x13, length = 0
● COLOR (сменить цвет): type = 0x20, length = 3, value интерпретируется как
новый цвет фонаря в RGB.
Предполагается, что в будущих версиях ПУФ могут появляться новые команды,
однако структура TLV останется неизменной.

Реализация фонаря должна удовлетворять следующим требованиям:

1. При запуске фонарь должен запрашивать хост:порт (по умолчанию
127.0.0.1:9999), подсоединяться по TCP и после этого начать отрабатывать
протокол управления.

2. При получении данных от сервера фонарь собирает целые команды (type +
length + value) и, если type известен, обрабатывает команду, иначе молча ее
игнорирует.

3. При получении команды ON фонарь включается (отрисовку фонаря оставляем
на ваше усмотрение).

4. При получении команды OFF фонарь выключается.

5. При получении команды COLOR фонарь меняет цвет.

6. При завершении работы фонарь корректно закрывает соединение с сервером.

7. Реализация фонаря позволяет легко добавлять любые новые команды.

Проработанность обработки исключительных ситуаций (ошибки установления

соединения, обрывы соединения) — на ваше усмотрение.

Технологические требования:

1. Задание принимается в виде исходников, готовых к сборке в QtCreator или с
помощью Make-файлов под Linux.

2. Код должен быть написан по Qt Coding Style.

3. Репозиторий с кодом должен быть доступен на Bitbucket или Github.

вторник, 2 июля 2013 г.

Компонент "Панель задач"

Наткнулся на qt-apps.org на компонент для Qt "Панель задач" (Task Panel). Подобные панели используются в проводнике Windows. По крайней мере использовались в XP, в семерке такой панели уже существенно меньше. Но тем не менее, может пригодиться.

Лицензия LGPL, то есть, можно использовать в коммерческих приложениях.
Проблем с использованием не обнаружил, единственно, что не понравилось - закругления уголков, немного подрихтовал напильником, чтобы было без сглаживания уголков.
Возможности компонента:
  • Группировка задач по блокам.
  • Возможность добавить свой виджет в блок. Стандартное решение - это размещение ссылок в блоках.
  •  Эффекты анимации при сворачивании/разворачивании блоков.
  • Возможность задать свою цветовую схему. По умолчанию предлагаются две стандартные схемы в стиле Windows XP.

среда, 6 февраля 2013 г.

Глобальный перехват событий

Если нужно поставить глобальный обработчик на все события то нужно переопределить метод
virtual boolnotify ( QObject * receiver, QEvent * e )

класса QApplication.
Например, если мы хотим перехватить все перемещения мышки, то нам поможет такой класс

class MyApp : public QApplication
{
public:
   MyApp(int & argc, char ** argv) : QApplication(argc, argv) {}
   
   virtual bool notify(QObject * receiver, QEvent * e)
   {
      if (e->type() == QEvent::MouseMove)
      {
         //обрабатываем событие
      }
      return QApplication::notify(receiver, e);
   }
};

понедельник, 4 февраля 2013 г.

Отключить системную кнопку close

Отключить системную кнопку Close у окна можно установив окну флаги:

  setWindowFlags(Qt::Window
     | Qt::WindowMinimizeButtonHint     
     | Qt::WindowMaximizeButtonHint     
     | Qt::CustomizeWindowHint);