пятница, ноября 09, 2012

Crusible qml highlighting scheme

Ссылка на qml.def файл. Для установки нужно скопировать файл в папку $FISHEYE_INST/syntax и перезапустить crusible.
Внешний вид:



пятница, ноября 02, 2012

Как указать путь к картинкам из QML, запакованного в ресурсный файл.

Проблема обсуждается тут. По большому счёту, это решение сейчас единственное:
  1. QString imagePath = QDir::currentPath()+"/images/";
  2. #if defined(Q_OS_MAC)
  3. imagePath = "file://"+imagePath;
  4. #endif
  5. QDeclarativeContext::setContextProperty("imagePath",imagePath);

О чем оно?

  1. Image {
  2.        id: image1
  3.        source: "images/face.png"

Указанный выше пример не будет работать, если qml упаковать в ресурсы и загрузить через  setSource. Решение в оригинальном топике, говорит, что мы можем прокинуть в qml из с++ переменную, содержащую путь к нашей папке с картинками, тогда:

  1. Image {
  2.        id: image1
  3.        source: imagePath + "images/face.png"

Будет работать. Однако, когда qml верстается это становится головной болью - эту переменную нужно будет определять в рутовом элементе, чтобы в нем и дочерних она была доступна. Не забыть удалить её перед сборкой ресурсного файла, т.к. setContextProperty из вашего с++ приложения будет переопределена уже в qml. Отлаживать при этом маленькие компоненты тоже не удобно - придется дублировать imagePath property и в них тоже.

В голову пришла забавная идея. А давайте напишем qml extension (https://github.com/misterion/QmlViewerDevHelper), который распарсит аргументы командной строки и позволит выставить проперти. QmlViewer имеет несколько аргументов(I/P), который отвечают за добавление папок к импорту dll. Они не валидируются и не ругаются, если в них написана ересь, т.е. можно написано -I "что угодно".

Напишем Qt Creator (Проекты -> Запуск)








Добавим dll и qmldir в папку  с плагинами (%QtDir%\%version%\imports). И запустим QmlViewer - теперь указанная нами переменная автоматом пробросится в qml.
Это очень удобно. Тем более, что параметры запуска QmlViewer хранятся в qmlproject.user и их не нужно комитить в репозитарий.

пятница, октября 26, 2012

QT QML WebSocket + SocketIO

Так вышло, что практически все попытки работать в с++ с websocket и socketio в частности базируются на библиотеке websocket++. На её базе есть клиент для socket.io. Есть даже врапер для websocket++ в qt.
У имеющихся решений есть одна, но весьма важная проблема , которой уже 7 месяцев и решения её пока нет. В мастер ветке  websocket++ ивент луп boost::asio::io_service запрятан в глубь библиотеки и где-то в этой глубине что-то явно не так :)
Между тем старая (0.1) версия websocket++ этой проблемы лишена и работает достаточно стабильно - именно её я взял за основу.
В итоге есть очень легковесная реализация SocketIO на qml + js работающая поверх с++ websocket, экспортируемого в qml.

Что в итоге:
import QtQuick 1.1
import "." as Elem

Rectangle {
    function newsHandler(body) {
        console.log('We have news', JSON.stringify(body));
        socket.emit('my other event', 'hello man!');
    }

    width: 360
    height: 360

    MouseArea {
        anchors.fill: parent
        onClicked: {
            socket.connect();
        }
    }

    Elem.SocketIO {
        id: socket
        uri: 'ws://localhost:8080'
        Component.onCompleted: {
            registerEvent('news', newsHandler);
        }
    }
}

понедельник, октября 22, 2012

Qt QML User-Agent

Работая над qGNA нам потребовалось менять user-agent в QML части приложения. Как оказалось из коробки это не работает (QTBUG-20473) и разработчики не считают нужным эту проблему исправлять. Решение через это не работает для XMLHttpRequest в qml. Однако вот такое небольшое решение эту проблему помогает обойти:

var xhr = new XMLHttpRequest();
xhr.setRequestHeader('QtBug', 'QTBUG-20473\r\nUser-Agent: ' + yourUserAgent);

понедельник, мая 28, 2012

QT. QMainWindow поверх других окон.

Казалось бы в чем проблема? Однако QMainWindow::activateWindow на win только задорно моргнет в трее, фактической активации окна не произойдет.
Использовать флаг Qt::WindowType::WindowStaysOnTopHint не всегда возможно - приложение не только будет поверх всего и всегда, но и перестанет "слушаться" сочетания WIN+D (свернуть всё).
Всегда можно получить handle окна и сделать все через win api, но можно и так:

  w.showMinimized();  
  w.setWindowState(Qt::WindowActive);  
  w.showNormal();  
  w.setFocus();