Tłumaczenie i adaptacja materiałów: dr Tomasz Xięski. Na podstawie prezentacji udostępnionych przez Digia Plc. na licencji CC.

Podobne dokumenty
Tłumaczenie i adaptacja materiałów: dr Tomasz Xięski. Na podstawie prezentacji udostępnionych przez Digia Plc. na licencji CC.

Tłumaczenie i adaptacja materiałów: dr Tomasz Xięski. Na podstawie prezentacji udostępnionych przez Digia Plc. na licencji CC.

Tłumaczenie i adaptacja materiałów: dr Tomasz Xięski. Na podstawie prezentacji udostępnionych przez Digia Plc. na licencji CC.

Qt in Education. Sieć I drukowanie

MVC w praktyce tworzymy system artykułów. cz. 1

The Graphics View Framework. Oprogramowanie i wykorzystanie stacji roboczych. Wykład 5. he Graphics View Framework - architektura

Wprowadzenie do tworzenia zaawansowanych interfejsów graficznych: QGraphics View Framework vs. QML. Jakub Bogacz. Patryk Górniak

- dodaj obiekt tekstowy: /** Maciej */ Stage { title : "First JavaFX App" scene: Scene { width: 300 height: 300 content: [ ] } }

Zarządzanie sieciami telekomunikacyjnymi

Programowanie w środowiskach RAD QtCreator, Qt i C++

Instrukcja obsługi User s manual

Programowanie w środowiskach RAD Qt i C++

Kurs programowania 2 - listy

Oprogramowanie i wykorzystanie stacji roboczych. Wykład 4

Testy jednostkowe - zastosowanie oprogramowania JUNIT 4.0 Zofia Kruczkiewicz

Podstawy programowania w Qt4

Qt - podstawowe cechy

MS Visual Studio 2005 Team Suite - Performance Tool

Qt - dialogi. Bogdan Kreczmer. ZPCiR ICT PWR pokój 307 budynek C3

GerbView. 20 grudnia 2015

1 LINQ. Zaawansowane programowanie internetowe Instrukcja nr 1

Programowanie obiektowe w VB cz 2

LCD (Liquid Crystal Display)

Instrukcja konfiguracji usługi Wirtualnej Sieci Prywatnej w systemie Mac OSX

Zmiany techniczne wprowadzone w wersji Comarch ERP Altum

Automatyczne generowanie testów z modeli. Bogdan Bereza Automatyczne generowanie testów z modeli

Założenia projektu: Projekt ma zadanie pokazać praktyczne zastosowanie App Inventor 2, poprzez stworzenie prostej aplikacji do nauki słówek.

Wzorce logiki dziedziny

PHP 5 język obiektowy

Dodanie nowej formy do projektu polega na:

Wykład 5_2 Arkusze stylów dziedziczenie. Technologie internetowe Zofia Kruczkiewicz

User s manual for icarwash

INSTRUKCJE JAK AKTYWOWAĆ SWOJE KONTO PAYLUTION

Dynamiczne i wydajne tworzenie interfejsu. Piotr Michałkiewicz

ASP.NET MVC. Podstawy. Zaawansowane programowanie internetowe Instrukcja nr 3

Wykład 5 Okna MDI i SDI, dziedziczenie

Programowanie Komputerów

TTIC 31210: Advanced Natural Language Processing. Kevin Gimpel Spring Lecture 9: Inference in Structured Prediction

Systemy wbudowane. Poziomy abstrakcji projektowania systemów HW/SW. Wykład 9: SystemC modelowanie na różnych poziomach abstrakcji

OpenPoland.net API Documentation

HTML (HyperText Markup Language) hipertekstowy język znaczników

PORÓWNANIE KILKU ZESTAWIEŃ OBROTÓW I SALD

Delphi podstawy programowania. Środowisko Delphi

Budowa nowoczesnej aplikacji SPA z wykorzystaniem biblioteki Ember.js

Camspot 4.4 Camspot 4.5

How to share data from SQL database table to the OPC Server? Jak udostępnić dane z tabeli bazy SQL do serwera OPC? samouczek ANT.


Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Temat 3. Projektowanie interfejsu użytkonwnika Kalkulator pierwszy program dla IOS

Qt sygnały i designer

Volcano MC-GM4 OPTICAL MOUSE USER S MANUAL MODECOM

Projektowanie aplikacji w modelu MVC opartej o framework CodeIgniter

Visual Studio instalacja

USB firmware changing guide. Zmiana oprogramowania za przy użyciu połączenia USB. Changelog / Lista Zmian

Programowanie obiektowe


Volcano MC-GMX4 OPTICAL MOUSE USER S MANUAL MODECOM

Programowanie obiektowe i zdarzeniowe wykład 4 Kompozycja, kolekcje, wiązanie danych

Poznaj ASP.NET MVC. Kamil Cieślak Microsoft Student Partner

Wprowadzenie do technologii JavaServer Faces 2.1 na podstawie

Komputerowe systemy na rynkach finansowych. wykład 5. MQL4 - funkcje operujące na obiektach wykresu

Kurs programowania. Wykład 13. Wojciech Macyna. 14 czerwiec 2017

WSNHiD, Programowanie 2 Lab. 2 Język Java struktura programu, dziedziczenie, abstrakcja, polimorfizm, interfejsy

Signals + Threads: Qt vs. Boost

Rys. 1. Główne okno programu QT Creator. Na rysunku 2 oznaczone zostały cztery przyciski, odpowiadają kolejno następującym funkcjom:

OSTC GLOBAL TRADING CHALLENGE MANUAL

Programowanie obiektowe

Network Services for Spatial Data in European Geo-Portals and their Compliance with ISO and OGC Standards

WYKONANIE APLIKACJI OKIENKOWEJ OBLICZAJĄCEJ SUMĘ DWÓCH LICZB W ŚRODOWISKU PROGRAMISTYCZNYM. NetBeans. Wykonał: Jacek Ventzke informatyka sem.

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

- Narzędzie Windows Forms. - Przykładowe aplikacje. Wyższa Metody Szkoła programowania Techniczno Ekonomiczna 1 w Świdnicy

Wprowadzenie do psql i SQL. Język komend psql. Podstawy instrukcji SELECT

Kowalski Marcin Wrocław, dn Jaśkiewicz Kamil Bazy Danych 1 Podstawy Projekt Temat: Baza danych do zarządzania projektami

Program szkoleniowy. 24 h dydaktycznych (18 h zegarowych) NAZWA SZCZEGÓŁY CZAS

strukturalny język zapytań używany do tworzenia i modyfikowania baz danych oraz do umieszczania i pobierania danych z baz danych

Office 365 Midsize Business

Bazy danych 10. SQL Widoki

TYLKO DO UŻYTKU WŁASNEGO! PERSONAL USE ONLY!

SubVersion. Piotr Mikulski. SubVersion. P. Mikulski. Co to jest subversion? Zalety SubVersion. Wady SubVersion. Inne różnice SubVersion i CVS

Wstęp do JUNG. Omówione elementy wykorzystane w Edge Color Project

Pobieranie argumentów wiersza polecenia

Tychy, plan miasta: Skala 1: (Polish Edition)

Pomoc do programu konfiguracyjnego RFID-CS27-Reader User Guide of setup software RFID-CS27-Reader

Zaawansowane Aplikacje Internetowe

SNP Business Partner Data Checker. Prezentacja produktu

Zarządzanie sieciami komputerowymi - wprowadzenie

Zasady rejestracji i instrukcja zarządzania kontem użytkownika portalu

USB firmware changing guide. Zmiana oprogramowania za przy użyciu połączenia USB. Changelog / Lista Zmian

Programowanie bazodanowe w.net. czyli SQL CLR w akcji

Aplikacje RMI Lab4

Java - interfejs graficzny

Programowanie obiektowe

Ćwiczenie 3 - Tworzenie zmiennych i połączeń animacyjnych w InTouch u

Microsoft Interface Definition Language

Tworzenie własnych komponentów

deep learning for NLP (5 lectures)

Logika rozmyta typu 2

Wprowadzenie do BD Operacje na bazie i tabelach Co poza zapytaniami? Algebra relacji. Bazy Danych i Systemy informacyjne Wykład 2.

Transkrypt:

Qt Quick

Tłumaczenie i adaptacja materiałów: dr Tomasz Xięski. Na podstawie prezentacji udostępnionych przez Digia Plc. na licencji CC. 2012 Digia Plc. The enclosed Qt Materials are provided under the Creative Commons Attribution-Share Alike 2.5 License Agreement. The full license text is available here: http://creativecommons.org/licenses/by-sa/2.5/legalcode. Digia, Qt and the Digia and Qt logos are the registered trademarks of Digia Plc. in Finland and other countries worldwide.

C++ jest dobrym wyborem do tworzenia aplikacji, a w szczególności: Struktur danych. Algorytmów. Logiki biznesowej. Prostych interfejsów użytkownika. C++ nie sprawdza się najlepiej w projektowaniu nowoczesnych i responsywnych interfejsów użytkownika gdzie: Wiele obiektów jest naraz aktywnych Występuje wiele często zależnych od siebie stanów Zmiany stanów i animacje muszą być płynne, reagować na zdarzenia np. czasowe

Wykorzystując Qt Quick, logika biznesowa i krytyczne operacje w dalszy ciągu mogą być zaimplementowane w C++ Interfejs użytkownika może zostać napisany korzystając z QML: QML - Qt Meta-object Language Język deklaratywny Bazuje na dobrze znanym języku Javascript

Qt Quick składa się z QML sam język Stworzony do budowania interfejsów użytkownika Może być wykorzystywany w innych zastosowaniach np. wymiana danych Qt Declarative moduł Qt Zawiera silnik QML, który tworzy interfejs Odwołania Qt <-> QML Mechanizmy do integracji C++ oraz QML Odpowiednich narzędzi i wsparcia w QtCreator

Qt Creator od wersji 2.0 wspiera QML Potrafi tworzyć projekty QML Potrafi uruchamiać i debugować QML

QML jest językiem deklaratywnym opartym na Java Script Dołączenie komponentów QtQuick Powiązanie właściwości i wartości import QtQuick 1.0 Rectangle { width: 200 height: 200 color: "red" Deklaracja elementu prostokąta stworzenie instancji obiektu Nazwy komponentów zawsze zaczynają się wielką literą

Dyrektywa import umożliwia dołączenie: Klas komponentów z modułów C++ Innych modułów QML plików Java Script import Qt 4.7 import MyCppClasses 1.2 import "from-qml" import "scripts.js" Gdy wykorzystywany jest moduł w C++, zawsze należy podać numer jego wersji

Tworząc elementy wewnątrz deklaracji innych elementów automatycznie tworzona jest ich hierarchia Rectangle { Rectangle { Text { Text { Text Text

Jest możliwym odwołanie się do obiektu rodzica używając jego nazwy. Rectangle { Rectangle { width: parent.width Text { color: parent.color Text {

Każdy element może mieć swój unikalny identyfikator (nazwę) Rectangle { id: outerrectangle... Do elementów odwołujemy się podając ich nazwę: { height: outerrectangle.height...

W QML wartości są przyporządkowywane nie są zwykle sztywnie przypisywane. W przykładzie zmiana położenia jednego prostokąta spowoduje zmianę położenia drugiego bo są od siebie zależne. Rectangle { id: firstrect x: 10... Rectangle { x: 400 - firstrect.x...

Zmiana wartości może być animowana Rectangle { id: firstrect Rectangle { x: 400 firstrect.x... SequentialAnimation { running: true loops: Animation.Infinite NumberAnimation { target: firstrect; property: "x"; to: 300 NumberAnimation { target: firstrect; property: "x"; to: 50

Podstawowe komponenty QtQuick: Rectangle prostokąt, Text tekst, Image obraz, BorderImage tworzy obramowanie na podstawie obrazu. Większość komponentów współdzieli szereg właściwości: x, y, szerokość (ang. width), wysokość (ang. height), kolor (ang. color), przeźroczystość (ang. opacity), widoczność (ang. visible), skalowanie (ang. scale), obrót (ang. rotation).

Możliwe jest wykorzystanie standardowych układów Qt (horizontal, vertical, grid), ale częściej stosuje się kotwice. Kotwice (ang. anchors) są wykorzystywane by przytwierdzić element do innego. Rectangle { Rectangle { anchors.fill: parent...... Rectangle { id: leftrectangle... Rectangle { anchors.left: leftrectangle.right...

Bardzo często kotwice stosowane są w połączeniu z marginesami: Rectangle { Rectangle { anchors.fill: parent anchors.margins: 5...... Rectangle { id: leftrectangle... Rectangle { anchors.left: leftrectangle.right anchors.leftmargin: 10...

Można przypiąć element do: lewej, górnej, prawej, dolnej części, wyśrodkować w pionie lub poziomie, linii bazowej Marginesy mogą być stosowane indywidualnie od siebie

Wykorzystując wbudowane w Qt typy układów można zrealizować klasyczny interfejs: Wartości muszą być wówczas przypisane, Odstępy między komórkami (ang. spacing) są globalne, Właściwość columns określa rozmiar siatki. Grid { columns: 2 spacing: 5 Rectangle { width: 20; height: 20; color: "red" Rectangle { width: 20; height: 20; color: "green" Rectangle { width: 20; height: 20; color: "blue"

Interakcja obsługiwana jest przez dodanie tzw. obszaru (ang. area), który jest niezależny od umieszczonych w nim komponentów graficznych: MouseArea obszar przechwytujący zdarzenia myszy GestureArea obszar dedykowany do obsługi gestów: Wspiera gesty dotykowe Niektóre proste urządzenia dotykowe mogą dostarczać jedynie zdarzenia identyfikowane jako Mouse Events. Zdarzenia związane z klawiaturą rejestruje komponent który aktualnie posiada focus.

Przycisk można zbudować korzystając z elementów: Rectangle, Text oraz MouseArea Rectangle { width: 200; height 100; color: "lightblue" Text { anchors.fill: parent text: "Press me!" Co się tutaj stało? Przyporządkowano funkcję javascript do sygnału MouseArea { anchors.fill: parent onclicked: { parent.color = "green"

Konieczność tworzenia wielu przycisków z trzech osobnych komponentów nie jest najlepszym rozwiązaniem. W QML występuje idea komponentów będących złożeniem poszczególnych elementów. Komponent może zostać powołany do życia tak samo jak pojedynczy element. Komponenty zazwyczaj tworzone są w osobnych plikach (modułach), które są dołączane dyrektywą include.

Plik Button.qml: import Qt 4.7 Rectangle { width: 200; height: 100; color: "lightblue" property alias text: innertext.text Text { id: innertext anchors.fill: parent MouseArea { anchors.fill: parent onclicked: { parent.color = "green"

Przyciski tworzone są w głównym pliku QML Główny plik QML powinien znaleźć się w tym samym katalogu co Button.qml W przeciwnym razie należy zaimportować katalog z Button.qml jako moduł import Qt 4.7 Row { spacing: 10 Button { text: "Oslo" Button { text: "Copenhagen" Button { text: "Helsinki" Button { text: "Stockholm"

Wykorzystując stany można łatwo tworzyć płynne animacje między zmianami zestawu właściwości normal large rotated

Właściwość states zawiera listę stanów w jakich może znajdować się element. import Qt 4.7 Rectangle { width: 400; height: 400; Rectangle { id: myrect width: 100; height: 100; anchors.centerin: parent color: "green"; states: [ State { name: "normal", State { name: "large", State { name: "rotated" ]

Każdy stan opisuje zestaw zmian właściwości Rectangle { states: [ State { name: "normal" PropertyChanges { target: myrect width: 100; height: 100; rotation: 0,... ]

Właściwość transitions opisuje w jaki sposób należy animować przejścia między zmianami stanów Rectangle { transitions: [ Transition { from: "*"; to: "normal" NumberAnimation { properties: "width, height" easing.type: Easing.InOutQuad duration: 1000 NumberAnimation { properties: "rotation" easing.type: Easing.OutElastic duration: 3000,... ]

Ustawienie stanu bezpośrednio: import Qt 4.7 Rectangle {... MouseArea { anchors.fill: parent onclicked: { if(parent.state == "normal") { parent.state = "rotated"; else if(parent.state ==...

Lub przez przypisanie stanu jako wartość odpowiedniej właściwości: import Qt 4.7 Rectangle {... state: mystate z poziomu której można się odwołać do kodu C++

Można przekazać wartości i obiekty jako zmienne globalne w QML. Takie przyporządkowanie wartości umożliwia logice biznesowej zapisanej w C++ kontrolowanie zmian w interfejsie QML. QML kontroluje wyłącznie interfejs użytkownika, wliczając w to tranzycie i inne efekty

QML jest wykonywany przez silnik QDeclarativeEngine Za jego pomocą można stworzyć dowolny element QML QGraphicsScene *scene = myexistinggraphicsscene(); QDeclarativeEngine *engine = new QDeclarativeEngine; QDeclarativeComponent component(engine, QUrl::fromLocalFile("myqml.qml")); QGraphicsObject *object = qobject_cast<qgraphicsobject *>(component.create()); scene->additem(object);

Łatwiej jest jednak stworzyć z widgetu QDeclarativeView Zawiera w sobie referencję do silnika QML Obsługuje tworzenie elementów QDeclarativeView *qmlview = new QDeclarativeView; qmlview->setsource(qurl::fromlocalfile("myqml.qml"));

Wszelkie operacje wykonywane są na warstwie kontekstu silnika QML Metoda setcontextproperty może być wykorzystana do ustawienia zmiennych globalnych QDeclarativeView *qmlview = new QDeclarativeView; QDeclarativeContext *context = qmlview->rootcontext(); context->setcontextproperty("mystate", QString("normal")); qmlview->setsource(qurl::fromlocalfile("myqml.qml"));

Wykorzystanie przyporządkowania a nie przypisania powoduje, że zmiana wartości właściwości w C++ implikuje zmianę w QML void Window::rotateClicked() { QDeclarativeContext *context = qmlview->rootcontext(); context->setcontextproperty("mystate", QString("rotated")); void Window::normalClicked() { QDeclarativeContext *context = qmlview->rootcontext(); context->setcontextproperty("mystate", QString("normal")); void Window::largeClicked() { QDeclarativeContext *context = qmlview->rootcontext(); context->setcontextproperty("mystate", QString("large"));

QObject uwidaczniany jest najczęściej jako tzw. context property, co umożliwia dostęp do slotów QDeclarativeView *qmlview = new QDeclarativeView; QLabel *mylabel = new QLabel; QDeclarativeContext *context = qmlview->rootcontext(); context->setcontextproperty("thelabel", mylabel); MouseArea { anchors.fill: parent onclicked: { thelabel.settext("hello Qt!");

Model MVC w Qt

The MVC pattern aims at separating the data (model) the visualization (view) modification (controller) View Model Controller Provides clear responsibilities for all classes involved

Separates the data from the visualization Avoids data duplication Can show the same data in multiple views Can use the same view for multiple data Separates the visualization from the modification Can use application specific actions when altering data The view only needs a single interface for all editing

Qt's Model-View classes are implemented in the Interview framework Model and view Delegate responsible for editing an item for visualization Selection model Model synchronizes selections between multiple views Delegate Selection Model View

The abstract model interface class QAbstractItemModel supports Lists items in one column, multiple rows Tables items in multiple rows and columns Trees nested tables

rowcount items List models consist of a range of items in a single row Each item is addressed by a QModelIndex

columncount rowcount A table model places the items in a grid of columns and rows

columncount parent rowcount child A tree model is a table with child tables Each sub-table has a QModelIndex as parent The top level root has an invalid QModelIndex as parent Only items of the first column can be parents

Each model has a data method used for reading QVariant QAbstractItemModel::data( const QModelIndex &index, int role) const The second argument, role, defaults to Qt::DisplayRole, but there are more roles DecorationRole for icons, pixmaps, colors, etc EditRole the data in an editable format FontRole the font used by the default renderer CheckStateRole the role to hold the items check state etc

The model index is used to address individual items of a model QAbstractItem model provides the following useful methods index(row, column, parent=qmodelindex()) rowcount(parent=qmodelindex()) columncount(parent=qmodelindex()) parent(index) The QModelIndex provides convenient methods data(role) child(row, column) parent()

In addition to the abstract interface, Qt provides a set of ready to use models QStringListModel a model exposing a QStringLis through the model interface QFileSystemModel a model exposing file system information (directories and files) QStandardItemModel a model populated by QStandardItem objects. Can be used to create lists, tables or trees

All views inherit the QAbstractItemView class Four views are provided QListView QTableView QTreeView QColumnView The QHeaderView widget is used to show headers for rows and columns

Shows a single column Use the modelcolumn property to select which column Provides both IconMode and ListMode

Shows a grid of items Use hiderow and hidecolumn to hide contents Show it again using showrow and showcolumn

Adapt the grid to the contents using resizecolumnstocontents and resizerowstocontents Access the headers using verticalheader and horizontalheader The stretchlastsection property lets the contents fill the width of the widget Headers can be hidden or shown Control the scrollbars using the horizontalscrollbarpolicy and verticalscrollbarpolicy properties

Shown multi-column trees Use setrowhidden and setcolumnhidden to hide and show contents Use expandall, expandtodepth and collapseall to control how much of the tree to show

Shows a tree of lists in separate columns Can hold a preview widget in the rightmost compartment

Using a QDataWidgetMapper, it is possible to map data from a model to widgets QDataWidgetMapper *mapper = new QDataWidgetMapper; mapper->setmodel(model); mapper->addmapping(cityedit, 0); mapper->addmapping(populationedit, 1); mapper->tofirst(); connect(nextbutton, SIGNAL(clicked()), mapper, SLOT(toNext())); connect(prevbutton, SIGNAL(clicked()), mapper, SLOT(toPrevious()));

Sometimes separating the model from the view is too complex No data duplication takes place The model will have to process the data and duplicate it internally For these scenarios, the QListWidget, QTableWidget and QTreeWidget exist Uses QListWidgetItem, QTableWidgetItem and QTreeWidgetItem respectively

The delegate is responsible for editing and item visualization The view uses and interacts with a delegate All delegates are derived from QAbstractItemDelegate By default, the QStyledItemDelegate is used. Model Delegate Selection Model View

The QStyledItemDelegate accepts the following Role Types data types CheckStateRole Qt::CheckState DecorationStyle DisplayRole EditRole QIcon, QPixmap, QImage and QColor QString (QVariant::toString()) The QItemEditorFactor class determines which widget to use for which data type Type bool double int / unsigned int QDate QDateTime QPixmap QString QTime Widget QComboBox QDoubleSpinBox QSpinBox QDateEdit QDateTimeEdit QLabel QLineEdit QTimeEdit

Custom delegates can be implemented to handle painting and/or editing For custom editing but standard painting it is possible to sub-class QItemEditorCreatorBase Delegates are assigned to an entire view, columns or rows of views

Painting depends on re-implementing the paint and sizehint methods class BarDelegate : public QStyledItemDelegate { Q_OBJECT public: explicit BarDelegate(int maxrange, QObject *parent = 0); void paint(qpainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; QSize sizehint(const QStyleOptionViewItem &option, const QModelIndex &index) const; private: int m_maxrange; ;

BarDelegate::BarDelegate(int maxrange, QObject *parent) : QStyledItemDelegate(parent), m_maxrange(maxrange) { QSize BarDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { return QSize(100, 1);

void BarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if(index.data().canconvert<int>()) { QRect barrect = QRect(option.rect.topLeft(), QSize(option.rect.width()*((qreal)index.data().toInt()/(qreal)m_maxRange), option.rect.height())); barrect.adjust(0, 2, 0, -2); if(option.state & QStyle::State_Selected) { painter->fillrect(option.rect, option.palette.highlight()); painter->fillrect(barrect, option.palette.highlightedtext()); else painter->fillrect(barrect, option.palette.text()); else QStyledItemDelegate::paint(painter, option, index);

tableview->setmodel(model); tableview->setitemdelegateforcolumn(1, new BarDelegate(3000000, this));

When editing, the view uses the delegate methods createeditor, seteditordata, setmodeldata and updateeditorgeometry class BarDelegate : public QStyledItemDelegate { Q_OBJECT public:... QWidget *createeditor(qwidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const; void seteditordata(qwidget *editor, const QModelIndex &index) const; void updateeditorgeometry(qwidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; void setmodeldata(qwidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;... It is common practice to rely on the EditRole and not the DisplayRole for editor data

QWidget *BarDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const { QSlider *slider = new QSlider(parent); slider->setrange(0, m_maxrange); slider->setorientation(qt::horizontal); slider->setautofillbackground(true); return slider; void BarDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const { QSlider *slider = qobject_cast<qslider*>(editor); if(slider) slider->setgeometry(option.rect);

void BarDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { QSlider *slider = qobject_cast<qslider*>(editor); if(slider) slider->setvalue(index.data(qt::editrole).toint()); void BarDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QSlider *slider = qobject_cast<qslider*>(editor); if(slider) model->setdata(index, slider->value(), Qt::EditRole);

tableview->setmodel(model); tableview->setitemdelegateforcolumn(1, new BarDelegate(3000000, this));

When working with delegates, it is useful to be able to pass more data between the model and delegate It is possible to declare user roles Use Qt::UserRole as first value in enum class CustomRoleModel : public QAbstractListModel { Q_OBJECT public: enum MyTypes { FooRole = Qt::UserRole, BarRole, BazRole ;...

It is possible to sort and filter models using a proxy model The QAbstractProxyModel provides mapping between models mapping of selections The QSortFilterProxyModel simplifies this by providing interfaces for filtering and sorting The dynamicsortfilter property controls whether the results are to be buffered or generated dynamically

If the sortingenabled property is set, clicking the header sorts the contents Applies to QTableView and QTreeView By using a QSortFilterProxyModel it is possible to sort on a given column and role sortrole default DisplayRole sortcasesensitivity

QSortFilterProxyModel *sortingmodel = new QSortFilterProxyModel(this); sortingmodel->sort(0, Qt::AscendingOrder); sortingmodel->setdynamicsortfilter(true); sortingmodel->setsourcemodel(model); nonsortedview->setmodel(model); sortedview->setmodel(sortingmodel);

To implement a more complex sorting algorithm, sub-class and re-implement lessthan method bool MySortProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { if(left.data().tostring().length() == right.data().tostring().length()) return left.data().tostring() < right.data().tostring(); else return (left.data().tostring().length() < right.data().tostring().length()); MySortProxyModel *customsortmodel = new MySortProxyModel(this); customsortmodel->sort(0, Qt::DescendingOrder); customsortmodel->setdynamicsortfilter(true); customsortmodel->setsourcemodel(model); customsortedview->setmodel(customsortmodel);

Filtering makes it possible to reduce the number of rows and columns of a model filterregexp / filterwildcard / filterfixedstring filtercasesensitivity filterrole filterkeycolumn

QSortFilterProxyModel *filteringmodel = new QSortFilterProxyModel(this); filteringmodel->setfilterwildcard("*stad*"); filteringmodel->setfilterkeycolumn(0); filteringmodel->setdynamicsortfilter(true); filteringmodel->setsourcemodel(model); nonfilteredview->setmodel(model); filteredview->setmodel(filteringmodel);

To implement more complex filters, sub-class and re-implement the filteracceptrow and filteracceptcolumn methods bool filteracceptsrow(int sourcerow, const QModelIndex &sourceparent) const { const QModelIndex &index = sourcemodel()->index(sourcerow, filterkeycolumn(), sourceparent); return index.data().tostring().contains("berg") index.data().tostring().contains("stad"); MyFilterProxyModel *customfiltermodel = new MyFilterProxyModel(this); customfiltermodel->setfilterkeycolumn(0); customfiltermodel->setdynamicsortfilter(true); customfiltermodel->setsourcemodel(model); customfilteredview->setmodel(customfiltermodel);

Selections are handled by selection models It is possible to tune a view to limit the selection Single items / rows / columns Single selection / contiguous / extended / multi / none A selection model can be shared between multiple views Model Delegate Selection Model View

view->setselectionbehavior( QAbstractItemView::SelectItems); view->setselectionmode( QAbstractItemView::SingleSelection); view->setselectionbehavior( QAbstractItemView::SelectRows); view->setselectionmode( QAbstractItemView::ContiguousSelection); view->setselectionbehavior( view->setselectionmode( QAbstractItemView::SelectColumns); QAbstractItemView::ExtendedSelection);

Sharing selections between views, combined with custom views can be a powerful tool listview->setmodel(model); tableview->setmodel(model); listview->setselectionmodel( tableview->selectionmodel());

Connect to the selection model, not to the view connect(view->selectionmodel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(updateSelectionStats())); void Widget::updateSelectionStats() { indexeslabel->settext(qstring::number(view->selectionmodel()->selectedindexes().count())); rowslabel->settext(qstring::number(view->selectionmodel()->selectedrows().count())); columnslabel->settext(qstring::number(view->selectionmodel()->selectedcolumns().count())); removebutton->setenabled(view->selectionmodel()->selectedindexes().count() > 0);