Ярлыки

среда, 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()
                }
            }

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