QT Desktop
QT Desktop
Team Emertxe
Fundamentals of Qt Module
Fundamentals of Qt
• The Story of Qt
• Developing a Hello World Application
• Hello World using Qt Creator
• Practical Tips for Developers
Objectives
• The Story of Qt
Some history
// main.cpp
#include <QtWidgets>
• helloworld.pro file
• lists source and header files
• provides project configuration
# File: helloworld.pro
SOURCES = main.cpp
• Assignment to variables
• Possible operators =, +=, -=
• Qmake-tutorial
Using qmake
• qmake tool
• Creates cross-platform makefiles
• Build project using qmake
cd helloworld
qmake helloworld.pro # creates Makefile
Make # compiles and links application
./helloworld # executes application
• Tip: qmake -project
• Creates default project file based on directory content
• Qmake manual
Qt Creator does it all for you
Fundamentals of Qt
• Operator overloading
Qt Documentation
• Reference Documentation
• All classes documented
• Contains tons of examples
• Qt Modules
• QtCore, QtGui, QtWidgets, QtXml, QtSql, QtNetwork,
QtTest .. See documentation
• Enable Qt Module in qmake .profile:
• QT += network
• Default: qmake projects use QtCore and QtGui
• Any Qt class has a header file.
#include <QLabel>
#include <QtWidgets/QLabel>
• Any Qt Module has a header file.
#include <QtGui>
Includes and
Compilation Time
Module includes
#include <QtGui>
• Precompiled header and the compiler
• If not supported may add extra compile time
• If supported may speed up compilation
• Supported on: Windows, Mac OS X, Unix
Class includes
#include <QLabel>
• Reduce compilation time
• Use class includes (#include <QLabel>)
• Forward declarations (classQLabel;)
Place module includes before other includes.
Summary
•
•
•
•
•
•
•
Core classes
Core classes
• Widget Centric
QObject
• Used intensively with QtWidget
• Less so when using Qt/C++ from QML QObject
• new QWidget(0)
• Widget with no parent="window"
• QWidget's children
• Positioned in parent's coordinate system
• Clipped by parent's boundaries
• QWidget parent
• Propagates state changes
• hides/shows children when it is hidden/shown itself
• enables/disables children when it is
enabled/disabled itself
Widgets contain
other widgets
• Container Widget
• Aggregates other child-widgets
• Use layouts for aggregation
• In this example: QHBoxLayout and QVBoxLayout
• Note: Layouts are not widgets
• Layout Process
• Add widgets to layout
• Layouts may be nested
• Set layout on container widget
Container Widget
// container (window) widget creation
QWidget* container = new QWidget;
QLabel* label = new QLabel("Note:", container);
QTextEdit* edit = new QTextEdit(container);
QPushButton* clear = new QPushButton("Clear", container);
QPushButton* save = new QPushButton("Save", container);
// widget layout
QVBoxLayout* outer = new QVBoxLayout();
outer->addWidget(label);
outer->addWidget(edit);
QHBoxLayout* inner = new QHBoxLayout();
inner->addWidget(clear);
inner->addWidget(save);
container->setLayout(outer);
outer->addLayout(inner); // nesting layouts
Demo
QVariant
• QVariant
• Union for common Qt "value types" (copyable, assignable)
• Supports implicit sharing (fast copying)
• Supports user types
• Use cases:
QVariant property(const char* name) const;
void setProperty(const char* name, const
QVariant &value);
class QAbstractItemModel {
virtual QVariant data( const QModelIndex&
index, int role );
}
• Qvariant Documentation
QVariant
• Q_Property is a macro:
Q_PROPERTY( type name READ getFunction [WRITE setFunction]
[RESET resetFunction] [NOTIFY notifySignal] [DESIGNABLE bool]
[SCRIPTABLE bool] [STORED bool] )
• Property access methods:
QVariant property(const char* name) const;
void setProperty(const char* name, const QVariant &value);
• If name is not declared as a Q_PROPERTY
• -> dynamic property
• Not accessible from Qt Quick.
Note:
• Q_OBJECT macro required for properties to work
• QMetaObject knows nothing about dynamic properties
Properties
• String Handling
QString
Strings can be created in a number of ways:
• Conversion constructor and assignment operators:
QString str(“abc”);
str = “def”;
• From a number using a static function:
QString n = QString::number(1234);
• From a char pointer using the static functions:
QString text = QString::fromLatin1(“Hello Qt”);
QString text = QString::fromUtf8(inputText);
QString text = QString::fromLocal8Bit(cmdLineInput);
QString text = QStringLiteral(“Literal String”);
(Assumed to be UTF-8)
• From char pointer with translations:
QString text = tr(“Hello Qt”);
QString
int i = ...;
int total = ...;
QString fileName = ...;
QString status = tr("Processing file %1 of %2:
%3")
.arg(i).arg(total).arg(fileName);
double d = 12.34;
QString str = QString::fromLatin1("delta:
%1").arg(d,0,'E',3);
// str == "delta: 1.234E+01"
• Safer: arg(QString,...,QString) (``multi-arg()'').
• But: only works with QString arguments.
QString
• length()
• endsWith() and startsWith()
• contains(), count()
• indexOf() and lastIndexOf()
Expression can be characters, strings, or regular
expressions
QString
• QString::split(), QStringList::join()
• QStringList::replaceInStrings()
• QStringList::filter()
QString
• QRegExp supports
• Regular expression matching
• Wildcard matching
• QString cap(int)
QStringList capturedTexts()
QRegExp rx(“^\\d\\d?$”); // match integers 0 to 99
rx.indexIn(“123”); // returns -1 (no match)
rx.indexIn(“-6”); // returns -1 (no match)
rx.indexIn(“6”); // returns 0 (matched as position 0)
• Regular expression documentation
Core classes
• Container Classes
Container Classes
Using QList
QList<QString> list;
list << “one” << “two” << “three”;
QString item1 = list[1]; // “two”
for(int i=0; i<list.count(); i++) {
const QString &item2 = list.at(i);
}
int index = list.indexOf("two"); // returns 1
Using QMap
QMap<QString, int> map;
map[“Norway”] = 5; map[“Italy”] = 48;
int value = map[“France”]; // inserts key if not exists
if(map.contains(“Norway”)) {
int value2 = map.value(“Norway”); // recommended lookup
}
Complexity
Sequential Container
Lookup Insert Append Prepend
Associative Container
Lookup Insert
• Common Widgets
• Layout Management
• Custom Widgets
Widgets
• Common Widgets
• Text widgets
• Value based widgets
• Organizer widgets
• Item based widgtes
• Layout Management
• Geometry management
• Advantages of layout managers
• Qt's layout managers
• Size policies
• Custom Widgets
• Rules for creating own widgets
Widgets
• Common Widgets
Text Widgets
• QLabel
label = new QLabel("Text", parent);
• setPixmap( pixmap ) - as content
• QLineEdit
line = new QLineEdit(parent);
line->setText("Edit me");
line->setEchoMode(QLineEdit::Password);
connect(line, SIGNAL(textChanged(QString)) ...
connect(line, SIGNAL(editingFinished()) ...
• QTextEdit
edit = new QTextEdit(parent);
edit->setPlainText("Plain Text");
edit->append("<h1>Html Text</h1>");
connect(edit,SIGNAL(textChanged(QString)) …
Button widgets
• QAbstractButton
Abstract base class of buttons
• QPushButton
button = new QPushButton("Push Me", parent);
button->setIcon(QIcon("images/icon.png"));
connect(button, SIGNAL(clicked()) ...
setCheckable(bool) - toggle button
• QRadioButton
radio = new QRadioButton("Option 1", parent);
• QCheckBox
check = new QCheckBox("Choice 1", parent);
Value Widgets
• QSlider
slider = new QSlider(Qt::Horizontal, parent);
slider->setRange(0, 99);
slider->setValue(42);
connect(slider, SIGNAL(valueChanged(int)) ...
• QProgressBar
progress = new QProgressBar(parent);
progress->setRange(0, 99);
progress->setValue(42);
// format: %v for value; %p for percentage
progress->setFormat("%v (%p%)");
• QSpinBox
spin = new QSpinBox(parent);
spin->setRange(0, 99);
spin->setValue(42);
spin->setSuffix(" USD");
connect(spin,SIGNAL(valueChanged(int)) ...
Organizer Widgets
• QGroupBox
box = new QGroupBox("Your Options", parent);
// ... set layout and add widgets
setCheckable( bool ) - checkbox in title
• QTabWidget
tab = new QTabWidget(parent);
tab->addWidget(widget, icon, "Tab 1");
connect(tab, SIGNAL(currentChanged(int)) ...
• setCurrentWidget( widget )
• Displays page assoziated by widget
• setTabPosition( position )
• Defines where tabs are drawn
• setTabsClosable( bool )
• Adds close buttons
Item Widgets
• QComboBox
combo = new QComboBox(parent);
combo->addItem("Option 1", data);
connect(combo, SIGNAL(activated(int)) ...
QVariant data = combo->itemData(index);
• setCurrentIndex( index )
• QListWidget
list = new QListWidget(parent);
list->addItem("Item 1");
// ownership of items with list
item = new QListWidgetItem("Item 2", list);
item->setCheckState(Qt::Checked);
connect(list, SIGNAL(itemActivated(QListWidgetItem*)) .
• Other Item Widgets: QTableWidget, QTreeWidget
Other Widgets
• QToolBox
Column of tabbed widget items
• QDateEdit, QTimeEdit, QDateTimeEdit
Widget for editing date and times
• QCalendarWidget
Monthly calendar widget
• QToolButton
Quick-access button to commands
• QSplitter
Implements a splitter widget
• QStackedWidget
Stack of widgets
Only one widget visible at a time
• Widget Documentation
Widgets
• Layout Management
Layout widgets
Definition
Layout: Specifying the relations of elements to each
other instead of the absolute positions and sizes.
• Advantages:
• Works with different languages.
• Works with different dialog sizes.
• Works with different font sizes.
• Better to maintain.
• Disadvantage
• Need to design your layout first.
Layout widgets
• QHBoxLayout
• Lines up widgets horizontally
• QVBoxLayout
• Lines up widgets vertically
• QGridLayout
• Arranges the widgets in a grid
• QFormLayout
• Lines up a (label, widget) pairs in two columns.
• QStackedLayout
• Arranges widgets in a stack
• only topmost is visible
QHBoxLayout &
QVBoxLayout
• Lines up widgets horizontally or vertically
• Divides space into boxes
• Each managed widgets fills in one box
• A two-column layout
• Column 1 a label (as annotation)
• Column 2 a widget (as field)
• Respects style guide of individual platforms.
QWidget* window = new QWidget();
QPushButton* one = new QPushButton("One");
...
QFormLayout* layout = new QFormLayout();
layout->addRow("One", one);
...
window->setLayout(layout)
• Form layout with clean looks and mac style
Hands-on
• Stretch
• Relative resize factor
• QBoxLayout::addWidget(widget, stretch)
• QBoxLayout::addStretch(stretch)
• QGridLayout::setRowStretch(row, stretch)
• QGridLayout::setColumnStretch(col, stretch)
• Contents Margins
• Space reserved around the managed widgets.
• QLayout::setContentsMargins(l,t,r,b)
• Spacing
• Space reserved between widgets
• QBoxLayout::addSpacing(size)
Layout Terms
• Strut
• Limits perpendicular box dimension
• e.g. height for QHBoxLayout
• Only for box layouts
• Min, max and fixed sizes
• QWidget::setMinimumSize( QSize )
• QWidget::setMaximumSize( QSize )
• QWidget::setFixedSize( QSize )
• Individual width and height constraints also available
• Nested Layouts
• Allows flexible layouts
• QLayout::addLayout(...)
Widgets
Size Policies
• Custom Widgets
Custom Widget
Creation
• It's as easy as deriving from QWidget
class CustomWidget : public QWidget
{
public:
explicit CustomWidget(QWidget* parent=0);
}
• If you need custom Signal Slots
• add Q_OBJECT
• Use layouts to arrange widgets inside, or paint the
widget yourself.
Custom Widget
Base class and Event Handlers
• Between objects
Signals & Slots
• Between Qt and the application
Events
• Between Objects on threads
Signal & Slots + Events
• Between Applications
DBus, QSharedMemory
Callbacks
General Problem
How do you get from "the user clicks a button" to your logic?
• Possible solutions
• Callbacks
• Based on function pointers
• Not type-safe
• Observer Pattern (Listener)
• Based on interface classes
• Needs listener registration
• Many interface classes
• Qt uses
• Signals and slots for high-level (semantic) callbacks
• Virtual methods for low-level (syntactic) events.
Object
communication
Demo QObject::connect(slider,SIGNAL(
valueChanged),progressbar,
SLOT(setValue))
Connection
variants
• Qt 4 style:
connect(slider,SIGNAL(valueChanged(int)),
progressBar, SLOT(setValue(int)));
• Using function pointers (Qt5):
connect( slider, &QSlider::valueChanged,
progressBar, &QSpinBox::setValue );
Demo
• Using non-member function:
static void printValue(int value) {...}
connect( slider, &QSignal::valueChanged,
&printValue );
Demo
Custom slots
• File: myclass.h
class MyClass : public QObject
{
Q_OBJECT // marker for moc
// ...
public slots:
void setValue(int value); // a custom slot
};
• File: myclass.cpp
void MyClass::setValue(int value) {
// slot implementation
}
Demo
Custom signals
• File: myclass.h
class MyClass : public QObject
{
Q_OBJECT // marker for moc
// ...
signals:
void valueChanged(int value); // a custom signal
};
• File: myclass.cpp
// No implementation for a signal
• Sending a signal
emit valueChanged(value);
• Demo
Q_OBJECT - flag
• Q_OBJECT
• Enhances QObject with meta-object information
• Required for signals
• Required for slots when using the Qt4 way
• moc creates meta-object information
• moc -o moc_myclass.cpp myclass.h
• c++ -c myclass.cpp; c++ -c moc_myclass.cpp
• c++ -o myapp moc_myclass.o myclass.o
• qmake takes care of mocing files for you
Variations of
Signal/Slot
Signal(s) Connect to Slot(s)
One Many
Many One
One Another
signal
Can ignore arguments, but not create values from nothing. Eg:
Signal Slot
setRange(int,int)
rangeChanged(int,int) setValue(int)
Update()
setValue(int)
valueChanged(int) Update()
X setRange(int,int)
textChanged(QSting) X setValue(int)
Hands-on
• Event Handling
Event Processing
Qt is an event-driven UI toolkit
Qapplication::exec() runs the event loop
1. Generate Events
• by input devices: keyboard, mouse, etc.
• by Qt itself (e.g. timers)
2. Queue Events
• by event loop
3. Dispatch Events
• by QApplication to receiver: QObject
• Key events sent to widget with focus
• Mouse events sent to widget under cursor
4. Handle Events
• by QObject event handler methods
Event Processing
QQuickMouseArea
Press me
QQuickView
QQuickMouseArea QQuickView
Event Processing
sendSpontaneousEvent
(QObject *, QEvent *)
QCoreApplication
1 event (QEvent *)
3 mousePressEvent (...) QWindow
2 event (...)
QQuickCanvas
MouseEvent QQuickView
Event Processing
mousePressEvent (QMouseEvent *)
QWindow
QQuickItem QQuickCanvas
QQuickMouseArea QQuickView
Event Handling
• QObject::event(QEvent *event)
• Handles all events for this object
• Specialized event handlers for QWidget and
QQuickItem:
• mousePressEvent() for mouse clicks
• touchEvent() for key presses
• Accepting an Event
• event->accept() / event->ignore()
• Accepts or ignores the event
• Accepted is the default.
• Event propagation
• Happens if event is ignored
• Might be propagated to parent widget
Demo
Event Handling
• Painting on Widgets
• Color Handling
• Painting Operations
• Style Sheets
Objectives
• Painting
• You paint with a painter on a paint device during a
paint event
• Qt widgets know how to paint themselves
• Often widgets look like we want
• Painting allows device independent 2D visualization
• Allows to draw pie charts, line charts and many
more
• StyleSheets
• Fine grained control over the look and feel
• Easily applied using style sheets in CSS format
Module
Objectives
Covers techniques for general 2D graphics and styling applications.
• Painting
• Painting infrastructure
• Painting on widget
• Color Handling
• Define and use colors
• Pens, Brushes, Palettes
• Shapes
• Drawing shapes
• Transformation
• 2D transformations of a coordinate system
• Style Sheets
• How to make small customizations
• How to apply a theme to a widget or application
Painting &
Styling
• Painting on Widgets
QPainter
• Controlled by QPainter
• Origin: Top-Left
• Rendering
• Logical - mathematical
• Aliased - right and below
• Anti-aliased – smoothing
• QSize(w,h)
• scale, transpose
• QPoint(x,y)
• QLine(point1, point2)
• translate, dx, dy
• QRect(point, size)
• adjust, move
• translate, scale, center
QSize size(100,100);
QPoint point(0,0);
QRect rect(point, size);
rect.adjust(10,10,-10,-10);
QPoint center = rect.center();
Painting &
Styling
• Color Handling
Color Values
• Using different color models:
• QColor(255,0,0) // RGB
• QColor::fromHsv(h,s,v) // HSV
• QColor::fromCmyk(c,m,y,k) // CMYK
• Defining colors:
QColor(255,0,0); // red in RGB
QColor(255,0,0, 63); // red 25% opaque (75%
transparent)
QColor("#FF0000"); // red in web-notation
QColor("red"); // by svg-name
Qt::red; // predefined Qt global colors
• Many powerful helpers for manipulating colors
QColor("black").lighter(150); // a shade of gray
• QColor always refers to device color space
QPen
Rule
The outline equals the size plus half the pen
width on each side.
• For a pen of width 1:
QPen pen(Qt::red, 1); // width = 1
float hpw = pen.widthF()/2; // half-pen width
QRectF rect(x,y,width,height);
QRectF outline = rect.adjusted(-hpw, -hpw, hpw, hpw);
• Due to integer rounding on a non-antialiased
grid, the outline is shifted by 0.5 pixel
towards the bottom right.
• Demo
QBrush
• Demo
Color Themes
and Palettes
• To support widgets color theming
• setColor(blue) not recommended
• Colors needs to be managed
• QPalette manages colors
• Consist of color groups
• enum QPalette::ColorGroup
• Resemble widget states
• QPalette::Active
• Used for window with keyboard focus
• QPalette::Inactive
• Used for other windows
• QPalette::Disabled
• Used for disabled widgets
Painting &
Styling
• Painting Operations
Drawing Figures
• Painter configuration
• pen width: 2
• pen color: red
• font size: 10
• brush color: yellow
• brush style: solid
• Demo
Drawing Text
• QFontMetrics
• calculate size of strings
QFont font("times", 24);
QFontMetrics fm(font);
int pixelsWide = fm.width("Width of this text?");
int pixelsHeight = fm.height();
Transformation
• Style Sheets
Qt Style Sheets
• Property Selector
• If property changes it is required to re-set style sheet
• Combining Selectors
• QLineEdit, QComboBox, QPushButton { color: red }
• Pseudo-States
• Restrict selector based on widget's state
• Example: QPushButton:hover {color:red}
• Demo
• Selecting Subcontrols
• Access subcontrols of complex widgets
• as QComboBox, QSpinBox, ...
• QComboBox::drop-down { image: url(dropdown.png) }
• Subcontrols positioned relative to other elements
• Change using subcontrol-origin and subcontrol-position
Cascading
• Main Windows
• Settings
• Resources
• Deploying Qt Applications
Objectives
• Settings
QSettings
• Configure QSettings
QCoreApplication::setOrganizationName("MyCompany");
QCoreApplication::setOrganizationDomain( "mycompany.com" );
QCoreApplication::setApplicationName("My Application");
• Typical usage
QSettings settings;
settings.setValue("group/value", 68);
int value = settings.value("group/value").toInt();
• Values are stored as QVariant
• Keys form hierarchies using '/'
• or use beginGroup(prefix) / endGroup()
• value() excepts default value
• settings.value("group/value", 68).toInt()
• If value not found and default not specified
Invalid QVariant() returned
Restoring State
• Store geometry of application
void MainWindow::writeSettings() {
QSettings settings;
settings.setValue("MainWindow/size", size());
settings.setValue("MainWindow/pos", pos());
}
• Restore geometry of application
void MainWindow::readSettings() {
QSettings settings;
settings.beginGroup("MainWindow");
resize(settings.value("size", QSize(400,
400)).toSize());
move(settings.value("pos", QPoint(200,
200)).toPoint());
settings.endGroup();
}
Application
creation
• Resources
Resource System
• Deploying Qt Applications
Ways of Deploying
• Static Linking
• Results in stand-alone executable
• +Only few files to deploy
• -Executables are large
• -No flexibility
• -You cannot deploy plugins
• Shared Libraries
• +Can deploy plugins
• +Qt libs shared between applications
• +Smaller, more flexible executables
• -More files to deploy
• Qt is by default compiled as shared library
• If Qt is pre-installed on system
• Use shared libraries approach
• Reference Documentation
Deployment
• Common Dialogs
QFileDialog
• Allow users to select files or directories
• Asking for a file name
QString fileName =
QFileDialog::getOpenFileName(this, tr("Open File"));
if(!fileName.isNull()) {
// do something useful
}
• QFileDialog::getOpenFileNames()
• Returns one or more selected existing files
• QFileDialog::getSaveFileName()
• Returns a file name. File does not have to exist.
• QFileDialog::getExistingDirectory()
• Returns an existing directory.
• setFilter("Image Files (*.png *.jpg *.bmp)")
• Displays files matching the patterns
QMessageBox
• Lab 9: Dialog
• Objectives
• Template code
Summary
Dialogs
and Designer
• Qt Designer
Qt Designer
• Widget Editing
• Change appearance of form
• Add layouts
• Edit properties of widgets
• Signal and Slots Editing
• Connect widgets together with signals & slots
• Buddy Editing
• Assign buddy widgets to label
• Buddy widgets help keyboard focus handling correctly
• Tab Order Editing
• Set order for widgets to receive the keyboard focus
UI Form Files
• Form stored in .ui file
• format is XML
• uic tool generates code
• From myform.ui
• to ui_myform.h
// ui_mainwindow.h
class Ui_MainWindow {
public:
QLineEdit *fileName;
... // simplified code
void setupUi(QWidget *) { /* setup widgets */ }
};
• Form ui file in project (.pro)
FORMS += mainwindow.ui
From .ui to C++
Form Wizards
// orderform.h
class Ui_OrderForm;
class OrderForm : public QDialog {
private:
Ui_OrderForm *ui; // pointer to UI object
};
• "Your Widget" derives from appropriate base class
• *ui member encapsulate UI class
• Makes header independent of designer generated code
Code Integration
// orderform.cpp
#include "ui_orderform.h"
OrderForm::OrderForm(QWidget *parent)
: QDialog(parent), ui(new Ui_OrderForm) {
ui->setupUi(this);
}
OrderForm::~OrderForm() {
delete ui; ui=0;
}
• Default behavior in Qt Creator
Signals and Slots
• Model/View Concept
• Custom Models
• Delegates
• Editing item data
• Data Widget Mapper
• Drag and Drop
• Custom Tree Model
Objectives
Using Model/View
• Introducing to the concepts of model-view
• Showing Data using standard item models
Custom Models
• Writing a simple read-only custom model.
• Editable Models
• Custom Delegates
• Using Data Widget Mapper
• Custom Proxy Models
• Drag and Drop
Model/View
• Model/View Concept
Why Model/View?
• Isolated domain-logic
• From input and presentation
• Makes Components Independent
• For Development
• For Testing
• For Maintenance
• Foster Component Reuse
• Reuse of Presentation Logic
• Reuse of Domain Model
Model/View
Components
Delegate
View Rendering
Rendering
Editing
Model
Data Demo
Model Structures
View Classes
• QtQuick ItemView
• Abstract base class for scrollable views
• QtQuick ListView
• Items of data in a list
• QtQuick GridView
• Items of data in a grid
• QtQuick PathView
• Items of data along a specified path
Model Classes
QAbstractItemModel
• QAbstractItemModel QAbstractListModel
• Abstract interface of models
QStringListModel
• Abstract Item Models
• Implement to use QAbstractTableModel
• Ready-Made Models
QAbstractProxyModel
• Convenient to use
• Proxy Models QSortFilterProxy
Model
• Reorder/filter/sort your items
• Model class documentation QFileSystemModel
QStandardItemModel
Data-Model-View
Relationships
• QSortFilterProxyModel
• Transforms structure of source model
• Maps indexes to new indexes
view = new QQuickView(parent);
// insert proxy model between model and
view
proxy = new
QSortFilterProxyModel(parent);
proxy->setSourceModel(model);
view->engine()->rootContext()-
>setContextProperty("_proxy", proxy);
Note: Need to load all data to sort or filter
Sorting/Filtering
• Custom Models
Implementing
a Model
• Variety of classes to choose from
• QAbstractListModel
• One dimensional list
• QAbstractTableModel
• Two-dimensional tables
• QAbstractItemModel
• Generic model class
• QStringListModel
• One-dimensional model
• Works on string list
• QStandardItemModel
• Model that stores the data
• Notice: Need to subclass abstract models
Step 1:
Read Only List Model
class MyModel: public QAbstractListModel {
public:
// return row count for given parent
int rowCount( const QModelIndex &parent)
const;
// return data, based on current index and
requested role
QVariant data( const QModelIndex &index,
int role = Qt::DisplayRole) const;
};
Demo
Step 2:
Header Information
QVariant MyModel::headerData(int section,
Qt::Orientation orientation,
int role) const
{
// return column or row header based on
orientation
}
Demo
Step 3:
Enabling Editing
// should contain Qt::ItemIsEditable
Qt::ItemFlags MyModel::flags(const QModelIndex &index) const
{
return QAbstractListModel::flags() | Qt::ItemIsEditable;
}
// set role data for item at index to value
bool MyModel::setData( const QModelIndex & index,
const QVariant & value,
int role = Qt::EditRole)
{
... = value; // set data to your backend
emit dataChanged(topLeft, bottomRight); // if successful
}
Demo
Step 4:
Row Manipulation
// insert count rows into model before row
bool MyModel::insertRows(int row, int count, parent)
{
beginInsertRows(parent, first, last);
// insert data into your backend
endInsertRows();
}
// removes count rows from parent starting with row
bool MyModel::removeRows(int row, int count, parent)
{
beginRemoveRows(parent, first, last);
// remove data from your backend
endRemoveRows();
}
Demo
Hands-on
• Delegates
Item Delegates
• QAbstractItemDelegate subclasses
• Control appearance of items in views
• Provide edit and display mechanisms
• QItemDelegate, QStyledItemDelegate
• Default delegates
• Suitable in most cases
• Model needs to provide appropriate data
• When to go for Custom Delegates?
• More control over appearance of items
Item Appearance
Data table
shown has no custom delegate
• Provides QComboBox
• for editing a series of values
• view->setItemDelegate( ... )
• view->setItemDelegateForColumn( ... )
• view->setItemDelegateForRow(... )
Type Based
Delegates
Demo
Model/View
• Mapping Setup
mapper = new QDataWidgetMapper(this);
mapper->setOrientation(Qt::Horizontal);
mapper->setModel(model);
// mapper->addMapping( widget, model-section)
mapper->addMapping(nameEdit, 0);
mapper->addMapping(addressEdit, 1);
mapper->addMapping(ageSpinBox, 2);
// populate widgets with 1st row
mapper->toFirst();
• Track Navigation
connect(nextButton, SIGNAL(clicked()),
mapper, SLOT(toNext()));
connect(previousButton, SIGNAL(clicked()),
mapper, SLOT(toPrevious()));
Demo
Mapped Property
• Setup of Model
• Model is ready by default
• model->mimeTypes()
• "application/x-qabstractitemmodeldatalist“
• "application/x-qstandarditemmodeldatalist"
• model->supportedDragActions()
• QDropEvent::Copy | QDropEvent::Move
• model->supportedDropActions()
• QDropEvent::Copy | QDropEvent::Move
• Setup of Item
item = new QStandardItem("Drag and Droppable Item");
// drag by default copies item
item->setDragEnabled(true);
// drop mean adding dragged item as child
item->setDropEnabled(true);
Demo
QAbstractItemModel
1. Read-OnlyModel
2. EditableModel
3. Insert-RemoveModel
4. LazyModel
5. Drag and DropModel
A Node Structure
class Node {
public:
Node(const QString& aText="No Data", Node
*aParent=0);
~Node();
QVariant data() const;
public:
QString text;
Node *parent;
QList<Node*> children;
};
Demo (node.h)
Read-Only Model
class ReadOnlyModel : public QAbstractItemModel {
public:
...
QModelIndex index( row, column, parent ) const;
QModelIndex parent child ) const;
int rowCount( parent ) const;
int columnCount( parent ) const;
QVariant data( index, role) const;
protected: // important helper methods
QModelIndex indexForNode(Node *node) const;
Node* nodeForIndex(const QModelIndex &index)
const;
int rowForNode(Node *node) const;
};
Editable Model
• QGraphicsScene is:
• a "model" for QGraphicsView
• a "container" for QGraphicsItems
QGraphicsScene
• setScene()
• sets the QGraphicsScene to use
• setRenderHints()
• antialiasing, smooth pixmap transformations, etc
• centerOn()
• takes a QPoint or a QGraphicsItem as argument
• ensures point/item is centered in View
• mapFromScene(), mapToScene()
• map to/from scene coordinates
• scale(), rotate(), translate(), matrix()
• transformations
QGraphicsItem
Demo
QGraphicsItem
methods
• pos()
• get the item's position in scene
• moveBy()
• Moves an item relative to its own position.
• zValue()
• get a Z order for item in scene
• show(), hide() - set visibility
• setEnabled(bool) - disabled items can not take focus
or receive events
• setFocus(Qt::FocusReason) - sets input focus.
• setSelected(bool)
• select/deselect an item
• typically called from
QGraphicsScene::setSelectionArea()
Select, Focus, Move
• QGraphicsItem::setFlags()
• Determines which operations are supported on an
item
• QGraphicsItemFlags
• QGraphicsItem::ItemIsMovable
• QGraphicsItem::ItemIsSelectable
• QGraphicsItem::ItemIsFocusable
item->setFlags(
QGraphicsItem::ItemIsMovable|QGraphicsIt
em::ItemIsSelectable);
Groups of Items
Each View and Item has its own local coordinate system
Coordinates
• Widgets in a Scene
Widgets in a Scene
Demo
Items
not widgets
• QGraphicsItem:
• Lightweight compared to QWidget
• No signals/slots/properties
• Scenes can easily contain thousands of Items
• Uses different QEvent sub-hierarchy (derived from
• QGraphicsSceneEvent)
• Supports transformations directly
• QWidget:
• Derived from QObject (less light-weight)
• supports signals, slots, properties, etc
• can be embedded in a QGraphicsScene with a
QGraphicsProxyWidget
QGraphicsWidget
#include <QtWidgets>
int main(int argc, char **argv) {
QApplication app(argc, argv);
QCalendarWidget *calendar = new
QCalendarWidget;
QGraphicsScene scene;
QGraphicsProxyWidget *proxy =
scene.addWidget(calendar);
QGraphicsView view(&scene);
view.show();
return app.exec();
}
QGraphicsLayout
• Override QGraphicsScene::dropEvent()
• To accept drop:
• acceptProposedAction()
• setDropAction(Qt::DropAction); accept();
• Override QGraphicsScene::dragMoveEvent()
• Optional overrides:
• dragEnterEvent(), dragLeaveEvent()
Hands-on
Graphics View
• Effects
Graphics Effects
• Performance Tuning
Level of Detail
Demo
Caching tips
• Cache item painting into a pixmap
• So paint() runs faster
• Cache boundingRect() and shape()
• Avoid recomputing expensive operations that stay the same
• Be sure to invalidate manually cached items after zooming
and other transforms
QRectF MyItem::boundingRect() const {
if (m_rect.isNull()) calculateBoundingRect();
return m_rect;
}
QPainterPath MyItem::shape() const {
if (m_shape.isEmpty()) calculateShape();
return m_shape;
}
setCacheMode()