Ярлыки

вторник, 9 октября 2018 г.

QML - в переводе добавить перенос строки

Если необходимо в ts файле перевода добавить перенос строки, то \n обычно не срабатывает. Тогда необходимо при редактировании ts файла нажать Enter.
Additional info here.

четверг, 27 сентября 2018 г.

QML - set default font

If you want set font for all items in ApplicationWindow. In main.cpp you must configure QFont and set it to QApplication.

    QApplication app(argc, argv);
    QFont font;
    font.setPixelSize(20);
    app.setFont(font);
}

Additional info here.

QtCreator highlight current line

If you want highlight current line in editor
Main menu: Tools > Options > Text Editor > Display > Highlight current line

QML - SystemPalette visible in all files

If you want use system colors create static variable in special singleton object.

// Style.qml
pragma Singleton
import QtQuick 2.11
QtObject {
     property SystemPalette palette: SystemPalette { colorGroup: SystemPalette.Active }
}

And then use it.

import QtQuick 2.0
Rectangle {
    color: Style.palette.highlight
}

Additional info here.

четверг, 30 августа 2018 г.

QtCreator - missing main menu

To open settings window in QtCreator
  • 1. Switch to debug mode
  • 2. Right click on 'Name|Value|Type' area
  • 3. In menu choose 'Configure debugger'
  • 4. Configure hot keys in 'Envioronment' tab

Additional info here.

четверг, 16 августа 2018 г.

Qt - check QObject derived class type

Example of using DelegateModel for hierarchical tree of data.

Tag* tag = new Tag();
Tag* tag_cast = qobject_cast<QObject*>(tag);
if(tag_cast) qDebug() << "Cool!";
else qDebug() << "oh..";

Additional info here and here.

понедельник, 16 июля 2018 г.

QML - nested ListView

Example of using DelegateModel for hierarchical tree of data.

import QtQuick 2.0
import QtQuick.Controls 2.2
import QtQml.Models 2.3

ListView {
    id: view
    anchors.fill: parent
    focus: true
    highlight: Rectangle {
        width: view.width; height: view.currentItem.height
        y: view.currentItem.y
        color: "blue"
    }
    highlightFollowsCurrentItem: true
    model: DelegateModel {
        model: catalogTreeModel //common QAbstractItemModel model
        delegate: Item {
            width: view.width; height: colDlg.height
            Column {
                id: colDlg
                width: view.width
                height: itemDlg.height + subView.height
                Item {
                    id: itemDlg
                    width: view.width
                    height: childrenRect.height
                    Text { text: session }
                    MouseArea {
                        anchors.fill: parent
                        propagateComposedEvents: true
                        onClicked: {
                            view.currentIndex = index
                            subView.shown = !subView.shown
                        } //onClicked:
                    } //MouseArea
                } //Item
                ListView { // nested ListView
                    id: subView
                    property int parentIndex: index
                    property bool isParrentSelected: view.currentIndex===index
                    property bool shown: false
                    width: view.width; height: shown ? /*_rowsCount * 25*/ subView.count * 25 : 0
                    visible: shown
                    enabled: shown
                    highlight: Rectangle {
                        id: subHighlight
                        visible: subView.isParrentSelected
                        focus: true
                        color: "red"
                    } //highlight:
                    model: DelegateModel {
                        model: catalogTreeModel
                        rootIndex: view.model.modelIndex(subView.parentIndex) // change root index for nested branch
                        delegate: Item {
                            width: view.width; height: txt.contentHeight
                            Text { id: txt; text: session }
                            MouseArea {
                                anchors.fill: parent
                                z: 1
                                hoverEnabled: true
                                propagateComposedEvents: true
                                onClicked: {
                                    subView.currentIndex = index
                                    view.currentIndex = subView.parentIndex
                                } //onClicked:
                            } //MouseArea
                        } //delegate:
                    } //model
                } //ListView
            } //Column
        } //delegate:
    } //model:
} //ListView

Additional info here.

пятница, 6 апреля 2018 г.

KDE - одинаковые панели на каждом экране

При подключении второго монитора в KDE обычно системная панель не появляется, поэтому ее необходимо добавить.
 - На экране нажимаем правую кнопку мыши.
   Add Panel > Default panel (если вы хотите настроить свою панель выберите Application Menu Bar)
 - Если панель появилась не на нужной стороне:
   Правой кнопкой мыши по панели.
   Panel Options > Panel Settings
   Нажимаем на Screen Edge и тащим к нужной грани экрана.

Более подробно тут.

понедельник, 2 апреля 2018 г.

QQuickItem добавить дочерний элемент

Если необходимо чтобы один элемент рисовал поверх другого, то его необходимо сделать потомком. Это можно сделать передав родительский QQuickItem в конструктор потомка или вызвав метод setParentItem(parent) в потомке.
Более подробно тут.

четверг, 29 марта 2018 г.

Qt - QAbstractItemModel обновить при добавлении содержимого

Для обновления связанных с моделью представлений необходимо использовать beginInsertRows() endInsertRows() во время добавления данных. А в конце еще выпустить сигнал dataChanged().
Более подробно тут.

QML - TreeView скроллинг к текущему элементу

Если размер содержимого превышает размер TableView необходимо проскроллировать до текущего элемента. Для этого необходимо использовать скрытую переменную __listView.

    __listView.positionViewAtIndex(row, mode)

Более подробно тут.

QML - ListView прокрутить до выбранного значения

Если содержимое ListView превышает его размеры, то возможно понадобится программно совершить прокрутку до выделенного элемента, для этого используется positionViewAtIndex

   ListView {
        id: listView
        onCurrentIndexChanged: {
            positionViewAtIndex(currentIndex, ListView.Visible)
        }
   }

Более подробно тут.

QML - TreeView выделить строку программно

Если есть необходимость выделить строку из JavaScript необходимо использовать selection.setCurrentIndex.

import QtQml.Models 2.2

TreeView {
    id: viewPerSe
    selection: ItemSelectionModel {
        model: viewPerSe.model
    }
}
function select (idx) {
    viewPerSe.selection.setCurrentIndex(idx, ItemSelectionModel.ClearAndSelect)
}

Более подробно тут и тут.

понедельник, 19 марта 2018 г.

QML - TableViewColumn delegate вывести значение роли

Если необходимо переписать делегат, и вывести значение содержащееся в роли можно воспользоваться специальным свойством styleData.value.

delegate: {
   Text { text: styleData.value }
}

Более подробно тут и тут.

четверг, 15 марта 2018 г.

QML - перенаправить вывод в свой C++ обработчик

Если есть необходимость использовать например свой логгер. Если это делать на стороне QML то могут возникнуть сложности с получением контекста, который хранит информацию о файле и строке. По аналогии с макросами __LINE__ __FILE__ в C++. Единственный найденный вариант это подменить обработчик сообщений методом qInstallMessageHandler().

#include 
#include 
#include 

void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    QByteArray localMsg = msg.toLocal8Bit();
    switch (type) {
    case QtDebugMsg:
        fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
        break;
    case QtInfoMsg:
        fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
        break;
    case QtWarningMsg:
        fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
        break;
    case QtCriticalMsg:
        fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
        break;
    case QtFatalMsg:
        fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
        abort();
    }
}

int main(int argc, char **argv)
{
    qInstallMessageHandler(myMessageOutput);
    QApplication app(argc, argv);
    ...
    return app.exec();
}

Более подробно тут, тут, тут и тут.

вторник, 13 марта 2018 г.

QBS - прописать define

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

        cpp.defines: ["CONFIG__H","QML_VER"]

Более подробно тут.

вторник, 6 марта 2018 г.

QML - Button сделать нажатой

Если необходимо после нажатия на Button оставить ее в нажатом состоянии. Можно установить свойство down в true.

            Button {
                id: but
                text: qsTr("Text")
                width: implicitWidth
                height: implicitHeight
                onClicked: {
                        down = true // button is visually down
                        checked = true // button is checked
                }
            }

Более подробно тут.

понедельник, 5 марта 2018 г.

QML - vertical TabBar

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

import QtQuick 2.0

            Item { //base component
                id: baseBar
                width: but1.height // width as TabBar height before rotation
                height: parent.height
                TabBar {
                    id: modeBar1
                    width: parent.height
                    height: but1.height

                    transform: [
                        Rotation { origin.x: 0; origin.y: 0; angle: -90} // rotate around the upper left corner counterclockwise
                        ,Translate { y: baseBar.height; x: 0 } // move to the bottom of the base
                    ]

                    TabButton {
                        id: but1
                        text: qsTr("Button1")
                    }
                    TabButton {
                        text: qsTr("Button2")
                } //TabBar
            } //Item

Более подробно тут.

пятница, 2 марта 2018 г.

QML - ListView highlight не виден

Возможно вы по ошибке в делегате используете Rectangle вместо Item. Тогда либо необходимо в Rectangle указать color: "transparent" либо заменить Rectangle на Item.
Более подробно тут и тут.

четверг, 1 марта 2018 г.

QML - определить что обьект принадлежит определенному типу

Начиная с Qt 5.10 появилась возможность проверять тип обьекта

import QtQuick 2.0

Item {
  // two QML items, used for type checking
  Item { id: testItem }
  Rectangle { id: testRect }

  // function to check wheter an item is a Rectangle
  function isRectangle(item) {
    return item instanceof Rectangle
  }

  // type check example
  Component.onCompleted: {
    console.log("testItem is Rectangle? "+isRectangle(testItem))
    console.log("testRect is Rectangle? "+isRectangle(testRect))
  }
}

Более подробно тут и тут.

QML - ListView перемещение области просмотра вслед за курсором

Если по каким-то причинам, при листании клавишами, курсор уходит за край вьюпорта, возможно стоит принудительно вызвать функцию positionViewAtIndex()

    ListView {
        id: list_view
        anchors.fill: parent
        focus: true //
        Keys.onUpPressed: decrementCurrentIndex() //перемещение стрелками
        Keys.onDownPressed: incrementCurrentIndex() //перемещение стрелками
        model: myModel
        onCurrentIndexChanged: {
            positionViewAtIndex(currentIndex, ListView.Visible)
        }
    } //ListView

Более подробно тут и тут.

среда, 28 февраля 2018 г.

QML - ListView включить обработку нажатия клавиш

Для включения обработки нажатия клавиш необходимо добавить соответствующий обработчик, например Keys.onUpPressed. И если этого оказалось недостаточно в событии onCompleted вызвать функцию forceActiveFocus(). Эта функция обходит дерево всех FocusScope и устанавливает focus: true а для последнего activeFocus: true. Так как только в такой конфигурации работают обработчики нажатия клавиш.

    ListView {
        id: list_view
        anchors.fill: parent
        focus: true //
        Keys.onUpPressed: decrementCurrentIndex() //перемещение стрелками
        Keys.onDownPressed: incrementCurrentIndex() //перемещение стрелками
        model: myModel
        Component.onCompleted: {
            forceActiveFocus(); //необходимо для обработки нажатия клавиш
            console.log("listView activeFocus: "+activeFocus)
        }
    } //ListView

Более подробно тут и тут.

среда, 21 февраля 2018 г.

QML - ListView удалить пропуски если делегат содержит пустое значение

Может создастся ситуация, когда модель возвращает пустое(NULL) значение. И в ListView появляются пустые строки. Для того, чтобы их скрыть необходимо в делегате установить параметры visible и enabled в false.

ListView {
    anchors.fill: parent
    delegate: Rectangle {
        width: model.vis ? 100 : 0
        height: model.vis ? 62 : 0
        visible: model.vis
        enabled: model.vis
        Rectangle {
            anchors.fill: parent
            color: model.rectcolor
        }
    }
    model: ListModel {
        ListElement {
            rectcolor: "red"
            vis:true
        }
        ListElement {
            rectcolor: "green"
            vis:false
        }
        ListElement {
         rectcolor: "brown"
         vis:true
        }
    }
}

Более подробно тут.

вторник, 20 февраля 2018 г.

QML - динамическое связывание свойств

Механизм property binding не распространяется на свойства, которые получают свои значения из JavaScript функций. Для того, чтобы заработал property binding, надо обернуть JavScript-функцию конструкцией Qt.binding( ... )

Keys.onSpacePressed: {
        height = Qt.binding(function() { return width * 3 })
    }

Более подробно тут и тут.

QML - ListView сворачивать/разворачивать секции

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

Rectangle {
    id: container
    width: 300
    height: 360

    ListModel {
        id: animalsModel
        ListElement { name: "Ant"; size: "Tiny" }
        ListElement { name: "Flea"; size: "Tiny" }
        ListElement { name: "Parrot"; size: "Small" }
        ListElement { name: "Guinea pig"; size: "Small" }
        ListElement { name: "Rat"; size: "Small" }
        ListElement { name: "Butterfly"; size: "Small" }
        ListElement { name: "Dog"; size: "Medium" }
        ListElement { name: "Cat"; size: "Medium" }
        ListElement { name: "Pony"; size: "Medium" }
        ListElement { name: "Koala"; size: "Medium" }
        ListElement { name: "Horse"; size: "Large" }
        ListElement { name: "Tiger"; size: "Large" }
        ListElement { name: "Giraffe"; size: "Large" }
        ListElement { name: "Elephant"; size: "Huge" }
        ListElement { name: "Whale"; size: "Huge" }
    }

    // The delegate for each section header
    Component {
        id: sectionHeading
        Rectangle {
            id: sectionHeadingRectangle
            width: container.width
            height: childrenRect.height
            color: "lightsteelblue"

            Text {
                text: section
                font.bold: true
                font.pixelSize: 20;
            }
            MouseArea {
                anchors.fill: parent
                onClicked: view.sectionClicked(section)
            }
        }
    }

    Component {
        id: section
        Rectangle {
            id: rect
            width: container.width
            height: shown ? mainText.height : 0
            visible: shown
            property bool shown: true

            Text { id: mainText; text: name; font.pixelSize: 18 }
            Connections {
                target: rect.ListView.view
                onSectionClicked: if (rect.ListView.section === name) shown = !shown;
            }
        }
    }

    ListView {
        id: view
        anchors.fill: parent
        // width: parent.width
        signal sectionClicked(string name)
        model: animalsModel
        delegate: section
        section.property: "size"
        section.criteria: ViewSection.FullString
        section.delegate: sectionHeading
    }
}

Более подробно тут и тут.

четверг, 15 февраля 2018 г.

QML - ListView получить индекс выбранной строки

Необходимо получить индекс модели по выбранной строке в ListView. Для этого в делегате ListView есть свойство index

ListView 
{
    delegate: Column
    {
        property int indexOfThisDelegate: index
        //...
    }
}

Более подробно тут и тут.

Qt - QSqlTableModel не сохраняет данные

Для сохранения данных в QSqlTableModel необходимо выбрать стратегию

 setEditStrategy(QSqlTableModel::OnManualSubmit);
обычно это делают в конструкторе. Затем производят запись методом insertRecord()

    QSqlRecord newRecord = record();
    newRecord.setValue("surname", surname);
    newRecord.setValue("name", name);
    if (!insertRecord(rowCount(), newRecord)) {
        qWarning() << "Failed to save data:" << lastError().text();
        return;
    }
и применяют изменения методом submitAll()

    if(!submitAll()){
        qWarning() << "Failed to submitAll:" << lastError().text();
    }
если после этого данные не сохраняются в БД, возможно не правильно настроенны первичные ключи, мне помогло включение AUTOINCREMENT для поля с первичным ключем. Более подробно тут.

среда, 14 февраля 2018 г.

QML - варианты обмена данными между компонентами

1.Использовать Connect

function clickHandler() {
    console.log('main clicked')
}
Component.onCompleted: {
    main.clicked.connect(clickHandler)
}


Connections {
 target: yourQmlObject 
 onClicked: foo(...)
 }

2.Использовать обработчик сигнала

Rectangle {
  YourQmlObject {
    onClicked: { ... }
  }
}

Более подробно тут и тут.

QML - TextEdit определить что содержимое было изменено

Для этого необходимо обрабатывать событие onTextChanged

TextInput {
    text: "Hello world!"
    onTextChanged: {
    }
}

Более подробно тут.

QML - MessageDialog возвращает предыдущее выбранное значение

Если использовать MessageDialog в QML так же как в Qt, то ничего не выйдет.

    MessageDialog {
        id: msgDialog
        text: qsTr("Current data is not saved.")
        informativeText: "Do you want to save your changes?"
        buttons: MessageDialog.Yes | MessageDialog.No | MessageDialog.Cancel
    }


    function handleChanges(){
        msgDialog.open()
        console.log(msgDialog.result)
        return msgDialog.result
    }

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

    MessageDialog {
        id: msgDialog
        text: qsTr("Current data is not saved.")
        informativeText: qsTr("Do you want to save your changes?")
        buttons: MessageDialog.Yes | MessageDialog.No | MessageDialog.Cancel
        onYesClicked: {
        }
        onNoClicked: {
        }
        onCancelClicked: {
        }
    }

Более подробно тут.

среда, 7 февраля 2018 г.

QML - QtCharts установка в Gentoo

1. emerge qtcharts
2. emerge --autounmask-write qtcharts
3. dispatch_conf
enter: q
enter: u
4. emerge qtcharts

QML - Dialog сделать модальным

Если необходимо диалог из Qt Quick 2 сделать модальным, т.е. блокирующим события ввода в основном окне.
Необходимо установить параметр modal в true.
Если это не помогло, настроить closePolicy.


Dialog {
    id: dialog
    title: qsTr("Dialog")
    x: (parent.width - width) / 2
    y: (parent.height - height) / 2
    width: parent.width - 20
    height: parent.height - 40
    closePolicy: "CloseOnEscape" | "CloseOnPressOutside"
    modal: true
    standardButtons: Dialog.Ok
}

Более подробно тут.

вторник, 6 февраля 2018 г.

QML - ListView установить фокус

Если в процессе работы в ListView перестают работать кнопки навигации (Keys.onUpPressed, Keys.onDownPressed), возможно необходимо принудительно установить фокус.
Для этого в делегате необходимо вызвать функцию forceActiveFocus().


           MouseArea {
                anchors.fill: parent
                onClicked: {
                    root.ListView.view.currentIndex = i
                    root.ListView.view.forceActiveFocus()
                }
            }

Более подробно тут.

вторник, 30 января 2018 г.

c++ лишние скобки при создании объекта

Ошибка: request for member `getStatus' in `test', which is of non-aggregate type `Bow ()()'

Решение: необходимо убрать скобки в Bow tst(); => Bow tst;

link

Qt Creator - включить profiler для QML.

Если при запуске профайлера появляется сообщение:
Could not connect to the in-process QML profiler.
Do you want to retry?

необходимо включить его поддержку.

Для включения профалера необходимо:
1. В левой панели Qt Creator выбрать вкладку Projects
2. Выбрать пункт Build.
    2.1. Развернуть элемент Build Steps.
    2.2. Включить галку Enable QML debugging.
3. Выбрать пункт Run.
    3.1. В разделе Debugger Settings вкючить галку Enable QML.
4. Для запуска профайлера, в верхнем меню Analyze/QML Profiler.

понедельник, 29 января 2018 г.

Qt/QML - создание файлов перевода

Для создания локализации приложения необходимо выполнить:

1. Создать файла перевода:
     lupdate file1.qml file2.qml -ts ru.ts
2. Редактировать ts файл:
    -удалить type="unfinished" в теге translation
    -написать перевод слова в тег translation
3. Создать бинарный файл из файла перевода:
    lrelease ru.ts
    должен появится файл ru.qm.
    Если у вас несколько ts файлов их можно обьединить в один:
        lconvert -i one.ts two.ts -o res.ts
4. Добавить в файл ресурса:
    <qresource prefix = "translations">
        <file>ru.qm</file>
    </qresource>
5. Загрузить в проект:
    QTranslator tran;
    tran.load(":translations/ru.qm");
    app.installTranslator(&tran);
Additional info here.

вторник, 23 января 2018 г.

Qt - масштабирование QQuickItem с сохранением позиции

При отрисовке QQuickItem мы переписываем updatePaintNode().
если необходимо смасштабировать обьект в ноде то применяем трансформационную ноду которую перемножаем на трансформационную матрицу.
для того, чтобы обьект остался на своем месте его необходимо сдвинуть в начало координат, а затем вернуть обратно.


QSGNode *quickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
    QRectF bounds = boundingRect();
    QSGNode *n = static_cast(oldNode);
    if (!n) {
        n = new QSGNode();
    } else {
                QSGTransformNode *transformNode = new QSGTransformNode;
                QMatrix4x4 m;
                m.translate(bounds.width()/2, bounds.height()/2,0);
                m.scale(0.1);
                m.translate(-bounds.width()/2, -bounds.height()/2,0);
                transformNode->setMatrix(m);
                n->appendChildNode(transformNode);

    }
    return n;
}


Более подробно тут.

пятница, 12 января 2018 г.

QML - смешивание Qt Quick Controls 1.x и 2.x

Чтобы избежать конфликта имен можно импортировать разные версии библиотек как алиасы

import QtQuick.Controls 2.2 as QC2
import QtQuick.Controls 1.4 as QC1
Item{
    QC1.Button{
    }
    QC2.Button{
    }
}

Более подробно тут и тут.

вторник, 9 января 2018 г.

QML - Ворнинги QML Connections: Cannot assign to non-existent property

Если все работает, но ворнинги появляются при использовании Connections можно попробовать установить ignoreUnknownSignals: true внутри Connections

    Connections {
        ignoreUnknownSignals: true // нужно что-бы убрать ворнинг QML Connections: Cannot assign to non-existent property
        target: contactsTab
        onSigWidthIsNull : {
            hideScrollBar(isNull)
        }
    }

Более подробно тут.