DesenvolvimentoCross-Platform com C++ e Qt
Sandro Santos [email protected]
http://liveblue.wordpress.com
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 2
Objetivos
● Apresentar as principais funcionalidades do Qt 4.6 utilizadas no desenvolvimento produtivo de aplicações cross-platform modernas
● Proporcionar uma vivência prática inicial das soluções mais utilizadas neste toolkit motivando a formação de novos desenvolvedores Qt / KDE
● Discutir decisões de projeto, idiomas e ferramentas auxiliares utilizados no Qt
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 3
Pré-requisitos
● Necessários:● Fundamentos de Orientação a Objetos (OO)● Experiência com alguma linguagem OO● Experiência com desenvolvimento de aplicações
visuais
● Desejáveis:● Fundamentos da linguagem Standard C++
● Especiais:● Padrões de projeto, estilos arquiteturais, application
frameworks etc
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 4
Metodologia
● Duração: 60 horas● Tópicos expositivos e laboratórios práticos● Referências:
● Livros● Qt Reference
Documentation● Fóruns
(QtCentre etc)● Qt Quarterly
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 5
Metodologia
● Duração: 60 horas● Tópicos expositivos e laboratórios práticos● Referências:
● Livros● Qt Reference
Documentation● Fóruns
(QtCentre etc)● Qt Quarterly
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 6
Sobre o instrutor
● Sandro Andrade– Doutorando pelo DMCC (UFBa)– Nove anos de experiência com desenvolvimento em Qt e
treze anos com C++– Dez anos de experiência em atividades docentes– Desenvolvedor KDE nos projetos KDevelop, Gluon e
Plasma. Membro do KDE e.V.– Co-fundador do Live Blue – Grupo de Desenvolvedores
KDE da Bahia– Desenvolvedor Qt certificado pela NOKIA
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 7
Visão Geral
● O Qt é um toolkit para desenvolvimento de aplicações cross-platform com recursos para IPC, networking, XML, SVG, banco de dados, scripting, OpenGL, animações, multi-touch, reconhecimento de gestos, multimídia e soluções mobile
● Disponível publicamente desde maio de 1995● Possui mais de 800 classes e 9000 funções● Utilizado em mais de 70 empresas de ponta● Possui licença dual (LGPL e comercial)
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 8
Histórico dos Toolkits Gráficos
● X11● Motif● Tcl / Tk● Fltk● WxWidgets● MFC / AWT / Swing● GTK / Qt
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 9
Visão Geral
● Módulos e ferramentas
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 10
Visão Geral
● Widgets
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 11
Visão Geral
● Dialogs e Main Windows
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 12
Visão Geral
● Dialogs e Main Windows
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 13
Visão Geral
● Dialogs e Main Windows
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 14
Visão Geral
● Gráficos 2D
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 15
Visão Geral
● Gráficos 2D
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 16
Visão Geral
● Gráficos 2D
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 17
Visão Geral
● Gráficos 2D
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 18
Visão Geral
● OpenGL
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 19
Visão Geral
● OpenGL
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 20
Visão Geral
● OpenGL
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 21
Visão Geral
● Scripting
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 22
Visão Geral
● Interfaces animadas
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 23
Visão Geral
● Model View
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 24
Visão Geral
● Banco de Dados
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 25
Visão Geral
● Networking
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 26
Visão Geral
● XML
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 27
Visão Geral
● Ferramentas (Qt Designer)
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 28
Visão Geral
● Ferramentas (Qt Linguist)
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 29
Visão Geral
● Ferramentas (Qt Assistant)
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 30
Visão Geral
● Qt Mobile
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 31
Visão Geral
● Qt Mobile
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 32
Visão Geral
● Qt Mobile
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 33
História do Qt
● Primeira versão disponibilizada em 1995, por Haavard Nord e Eirik Chambe-Eng
● Seu desenvolvimento se iniciou em 1991 e em 1993 já existia um núcleo que suportava widgets
● A letra 'Q' foi escolhida porque ela aparecia de forma bonita no editor emacs de Haavard :)
● O “t” vem da palavra toolkit● Em 1994 foi fundada a Trolltech, antes Troll
Tech e ainda antes Quasar Technologies
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 34
História do Qt
● Em 1996 foi lançado o Qt 1.1 e a Trolltech tinha 8 clientes
● Também em 1996 o projeto KDE (na época The K Desktop Environment) foi fundado por Matthias Ettrich
● O 'K' (do KDE) era simplesmente a letra que vinha antes do 'L' (do Linux) :)
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 35
História do Qt
● Em 1997 o Qt passa a ser utilizado no desenvolvimento do KDE e a versão 1.3 é lançada
● Em 1999, o Qt2 passa a ser licenciado pela QPL (Qt Public License)
● Em 2000 é lançado o Qtopia (Qt para ambientes mobile)
● Neste mesmo, o Qt passa a ser licenciado pela GPL (GNU Public License)
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 36
História do Qt
● Em 2001 é lançado o Qt3● Em 2005 é lançado o Qt4: primeira versão
open-source em todas as plataformas● Em janeiro de 2008 a Trolltech é comprada
pela Nokia (Qt Software → Qt Development Frameworks)
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 37
História do Qt
● Em 2009 o Qt passa a ser liberado sob a licença LGPL e seus repositórios se tornam abertos a contribuições da comunidade (qt.gitorious.org)
● Em 2010 o Qt adota o modelo de Open Governance
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 38
Porque o Qt ?
● Quem usa o Qt ?
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 39
Instalando o Qt 4.6
● Linux:● Via compilação dos fontes obtidos em qt.nokia.com
ou qt.gitorious.org● Via binários disponibilizados através de pacotes
para a sua distribuição● Geralmente existem pacotes separados para:
– Bibliotecas e headers– Ferramentas (Designer, Linguist e Assistant)– Demos– Documentação– Qt Creator (IDE)
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 40
Instalando o Qt 4.6
● Windows:● Fazer o download do Qt SDK para Windows● Executar o programa de instalação● O programa de instalação irá fazer o download do
MinGW (Minimalist GNU for Windows)● Pode ser utilizado com o Microsoft Visual C++ ou
Eclipse, além do Qt Creator
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 41
Lab1: Hello Qt
1 #include <QApplication>2 #include <QLabel>34 int main(int argc, char *argv[])5 {6 QApplication app(argc, argv);7 QLabel *label = new QLabel("Hello Qt!");8 label->show();9 return app.exec();10 }
● Executar:
$ qmake -project
$ qmake
$ make
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 42
Lab1: Hello Qt
● O qmake:● Ferramenta que automatiza o processo de
compilação, linking e instalação em diferentes plataformas
● Realiza a geração automática de Makefiles a partir de arquivos de projeto de fácil criação
● O arquivo de projeto pode ser criado pelo desenvolvedor ou automaticamente pelo qmake (opção -project)
● Os módulos QtCore e QtGui são automaticamente incluídos no processo de linking
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 43
Lab1: Hello Qt
● O qmake:
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 44
Lab1: Hello Qt
1 ###################################################################2 # Automatically generated by qmake (2.01a) qua jul 21 22:43:25 20103 ###################################################################45 TEMPLATE = app6 TARGET = 7 DEPENDPATH += .8 INCLUDEPATH += .910 # Input11 SOURCES += main.cpp
● O qmake:● Arquivo de projeto automaticamente gerado neste
exemplo
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 45
Lab1: Hello Qt
● O qmake - principais configurações:– Controlando a informação de debug:
CONFIG += qt [ debug | release | debug_and_release ]– Inclusões dependentes de plataforma:
win32 { SOURCES += hellowin.cpp }unix { SOURCES += hellounix.cpp }
– Tipos de template:● app = programa executável● lib = biblioteca. CONFIG pode conter dll, staticlib ou plugin● subdirs = união de todos os projetos dos diretórios em SUBDIRS
– Plugins: adicione plugin à variável CONFIG– Plugin do Qt Designer: adicione plugin e designer à
variável CONFIG
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 46
Lab1: Hello Qt
● O qmake - principais configurações:– Adicionando e removendo módulos do Qt:
“QT +=” e “QT -=”– Utilizando outras bibliotecas;
● Adicionando caminhos para os headers:INCLUDEPATH = c:/msdev/include d:/stl/include
● Adicionando bibliotecas:LIBS += -L/usr/local/lib -lmath
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 47
Lab1: Hello Qt
● Algumas considerações:● O QLabel é um dos muitos widgets (windows
gadgets) do Qt● Widgets podem conter outros widgets● A janela principal de um programa Qt geralmente é
um QMainWindow ou QDialog contendo outros widgets
● Entretanto, qualquer widget pode representar a janela principal (neste exemplo, um QLabel)
● Por default, todos os widgets são criados ocultos
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 48
Lab1: Hello Qt
● Algumas considerações:● O Qt tem sido cada vez mais utilizado no
desenvolvimento de aplicações console (sem interface gráfica), devido às grandes facilidades adicionadas pelo seu modelo de objetos
● Nestes casos não é necessário realizar o link com o módulo QtGui e deve-se adicionar a instrução “QT -= gui” no arquivo de configuração do qmake
● Tais aplicações devem utilizar a classe QCoreApplication on invés de QApplication
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 49
Modelo de Objetos do Qt
● O Qt estende o modelo de objetos do C++ com as seguintes funcionalidades:● Signals / Slots: mecanismo desacoplado para
comunicação (um-muitos) entre objetos● Object properties: atributos dinâmicos● Meta-Objects: para operações RTTI (Run-Time
Type Information) e de Introspecção● Eventos e filtros de eventos● Tradução contextual de strings para
internacionalização
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 50
Signals / Slots
● Representam um mecanismo central do Qt● Signals e slots são por padrão processados
imediatamente no momento da sua execução● Um signal é uma mensagem que está presente
em uma classe como uma declaração de uma função-membro void. Signals não são invocados, mas emitidos (via emit) por um objeto da classe
● Um slot é uma função-membro void e pode ser normalmente invocada
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 51
Signals / Slots
1 bool QObject::connect(senderqobjptr,2 SIGNAL(signalname(argtypelist)),3 receiverqobjptr,4 SLOT(slotname(argtypelist))5 optionalConnectionType);
● Um signal de um objeto pode ser conectado a slots de um ou mais outros objetos, desde que os parâmetros sejam compatíveis
● Sintaxe de conexão:
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 52
Signals / Slots
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 53
Lab2: Signals / Slots
1 #include <QObject>23 class Counter : public QObject4 {5 Q_OBJECT6 public:7 Counter() { m_value = 0; }8 int value() const { return m_value; }9 public slots:10 void setValue(int value);11 signals:12 void valueChanged(int newValue);13 private:14 int m_value;15 };
● Um exemplo simples:
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 54
Lab2: Signals / Slots
1 void Counter::setValue(int value)2 {3 if (value != m_value) {4 m_value = value;5 emit valueChanged(value);6 }7 }8910 Counter a, b;11 QObject::connect(&a, SIGNAL(valueChanged(int)),12 &b, SLOT(setValue(int)));1314 a.setValue(12); // a.value() == 12, b.value() == 1215 b.setValue(48); // a.value() == 12, b.value() == 48
● Um exemplo simples:
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 55
Lab2: Signals / Slots
● Considerações importantes:● Slots são funções comuns do C++: podem ser
invocadas diretamente, sobrecarregadas, públicas ou privadas
● Um signal pode ser conectado a vários slots● Mais de um signal pode ser conectado ao mesmo
slot (o emissor pode ser descoberto com QObject::sender);
● Um signal pode ser conectado a outro signal
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 56
Lab2: Signals / Slots
● Considerações importantes:● Conexões podem ser removidas com
QObject::disconnect● Um signal pode ter um número de parâmetros
maior ou igual ao número de parâmetros do slot conectado
● Signals e slots podem ser utilizados em qualquer classe derivada de QObject, não somente widgets
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 57
Lab2: Signals / Slots
● Considerações importantes:● Conexões, em QDialogs, podem ser
automaticamente realizadas (sem requerer o QObject::connect)
● Se as palavras reservadas signals, slots e emit estiverem sendo utilizadas por outra biblioteca (ex. boost) pode-se desabilitá-las e usar as macros Q_SIGNALS, Q_SLOTS e Q_EMIT
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 58
Signals / Slots
● Como signals e slots são implementados ?● As palavras reservadas signals, slots e emit (bem
como foreach e recursos de meta-objetos, propriedades etc) não estão presentes no Standard C++
● Essas extensões são tratadas pelo MOC (Meta-Object Compiler)
● O qmake verifica quais classes, declaradas na variável HEADER, utilizam a macro Q_OBJECT e automaticamente inclui a invocação do moc no arquivos Makefile gerados
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 59
Signals / Slots
● Como signals e slots são implementados ?● O MOC (Meta-Object Compiler)
Código comextensões do QtEx: Q_OBJECT
public slots:
MOC(Meta-Object
Compiler)
CódigoStandard C++
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 60
Layout e Parentesco
● Layouts gerenciam a geometria dos widgets de uma janela
● Um widget pode ter uma relação de parentesco com outro widget
● Exemplo:
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 61
Layout e Parentesco
● Layouts gerenciam a geometria dos widgets de uma janela
● Um widget pode ter uma relação de parentesco com outro widget
● Exemplo:QWidget (top-level window)
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 62
Layout e Parentesco
● Layouts gerenciam a geometria dos widgets de uma janela
● Um widget pode ter uma relação de parentesco com outro widget
● Exemplo:QWidget (top-level window)
QSlider (filho do QWidget)
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 63
Layout e Parentesco
● Layouts gerenciam a geometria dos widgets de uma janela
● Um widget pode ter uma relação de parentesco com outro widget
● Exemplo:QWidget (top-level window)
QSlider (filho do QWidget)
QSpinBox (filho do QWidget)
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 64
Layout e Parentesco
● Tipos de layout:– QHBoxLayout
– QVBoxLayout QGridLayout QformLayout
– Layouts dinâmicos e em fluxo
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 65
Layout e Parentesco
● Conexão de signals e slots
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 66
Lab3: Layout e Parentesco
15 QObject::connect(spinBox, SIGNAL(valueChanged(int)), slider,
SLOT(setValue(int)));19 QObject::connect(slider,
SIGNAL(valueChanged(int)), spinBox,
SLOT(setValue(int)));20 spinBox->setValue(35);21 QHBoxLayout *layout =
new QHBoxLayout;22 layout->addWidget(spinBox);23 layout->addWidget(slider);24 window->setLayout(layout);25 window->show();26 return app.exec();27 }
1 #include <QApplication>2 #include <QHBoxLayout>3 #include <QSlider>4 #include <QSpinBox>56 int main(int argc, char *argv[])7 {8 QApplication app(argc, argv);9 QWidget *window = new QWidget;10 window->setWindowTitle
("Enter Your Age");11 QSpinBox *spinBox =
new QSpinBox;12 QSlider *slider =
new QSlider(Qt::Horizontal);13 spinBox->setRange(0, 130);14 slider->setRange(0, 130);
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 67
Lab3: Layout e Parentesco
● Considerações sobre relações de parentesco:– O pai automaticamente assume a responsabilidade de
liberação de memória de todos os filhos– Os filhos são liberados quando o pai sair do escopo– Os únicos objetos a serem deletados manualmente são
os criados com new e que não possuem pai– Se um filho é deletado antes do pai ele é
automaticamente excluído da lista de filhos do pai– Widgets filhos são vistos dentro da área do pai– A execução do show() no pai automaticamente exibe
todos os filhos
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 68
Lab3: Layout e Parentesco
● Hierarquia das classes utilizadas:
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 69
Qt e IDE's
● Principais IDE's multi-plataforma:● Qt Creator (IDE oficial do Qt)● KDevelop (http://www.kdevelop.org)● XCode (http://developer.apple.com/tools/xcode/)● Visual Studio (http://msdn.microsoft.com/en-
us/vstudio)● Eclipse (http://www.eclipse.org/)● Edyuk (http://www.edyuk.org)● QDevelop (http://www.qdevelop.org/)
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 70
Qt Reference Documentation
● http://doc.qt.nokia.com/4.6/
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 71
Main Windows e Dialogs
● Uma aplicação é geralmente formada por uma tela principal (QMainWindow) e por várias outras telas (QDialog)
● Essas telas podem ser criadas manualmente ou através do Qt Designer
● Exemplo(Dialog):
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 72
Main Windows e Dialogs
● Layout e relações de parentesco:
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 73
Main Windows e Dialogs
● Dialogs pré-existentes no Qt:
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 74
Main Windows e Dialogs
● Dialogs pré-existentes no Qt:
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 75
Lab4: Dialogs
15 void findPrevious( const QString &str,
Qt::CaseSensitivity cs);16 private slots:17 void findClicked();18 void enableFindButton(
const QString &text);19 private:20 QLabel *label;21 QLineEdit *lineEdit;22 QCheckBox *caseCheckBox;23 QCheckBox *backwardCheckBox;24 QPushButton *findButton;25 QPushButton *closeButton;26 };
1 #include <QDialog>23 class QCheckBox;4 class QLabel;5 class QLineEdit;6 class QPushButton;78 class FindDialog : public QDialog9 {10 Q_OBJECT11 public:12 FindDialog
(QWidget *parent = 0);13 signals:14 void findNext(
const QString &str, Qt::CaseSensitivity cs);
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 76
Lab4: Dialogs
15 findButton->setDefault(true);16 findButton->setEnabled(false);1718 closeButton = new
QPushButton(tr("Close"));1920 connect(lineEdit,
SIGNAL(textChanged( const QString &)),
this, SLOT(enableFindButton(
const QString &)));2122 connect(findButton,
SIGNAL(clicked()), this, SLOT(findClicked()));
2324 connect(closeButton,
SIGNAL(clicked()),25 this, SLOT(close()));
1 #include <QtGui>2 #include "finddialog.h"34 FindDialog::FindDialog(
QWidget *parent) : QDialog(parent)
5 {6 label = new QLabel(
tr("Find &what:"));7 lineEdit = new QLineEdit;8 label->setBuddy(lineEdit);910 caseCheckBox =
new QCheckBox(tr("Match &case"));1112 backwardCheckBox =
new QCheckBox( tr("Search &backward"));
1314 findButton = new
QPushButton(tr("&Find"));
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 77
Lab4: Dialogs
39 QHBoxLayout *mainLayout = new QHBoxLayout;
40 mainLayout->addLayout(leftLayout);
41 mainLayout->addLayout( rightLayout);
42 setLayout(mainLayout);4344 setWindowTitle(tr("Find"));4546 setFixedHeight(
sizeHint().height());47 }
26 QHBoxLayout *topLeftLayout = new QHBoxLayout;
27 topLeftLayout->addWidget(label);28 topLeftLayout->addWidget(
lineEdit);2930 QVBoxLayout *leftLayout =
new QVBoxLayout;31 leftLayout>addLayout(
topLeftLayout);32 leftLayout->addWidget(
caseCheckBox);33 leftLayout->addWidget(
backwardCheckBox);3435 QVBoxLayout *rightLayout =
new QVBoxLayout;36 rightLayout->addWidget(
findButton);37 rightLayout->addWidget(
closeButton);38 rightLayout->addStretch();
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 78
Main Windows e Dialogs
● Main Windows são widgets que podem conter menus, toolbars e barra de status
● Main Windows são criadas através da derivação da classe QMainWindow
● O Qt Designer facilita sobremaneira a criação de Main Windows e Dialogs
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 79
Main Windows e Dialogs
● Áreas definidas pela QMainWindow
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 80
Main Windows e Dialogs
● Menus e toolbars baseiam-se no conceito de action:● Um action é um item que pode ser adicionado a
qualquer número de menus e toolbars
● Criar menus e toolbars requer três passos:● Criação e configuração dos actions● Criação do menu e utilização dos actions● Criação das toolbars e utilização dos actions
● Todo action possui o signal triggered()
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 81
Lab5: Main Windows
1 QAction *newAction = new QAction(tr("&New"), this);2 newAction->setIcon(QIcon(":/images/new.png"));3 newAction->setShortcut(tr("Ctrl+N"));4 newAction->setStatusTip(tr("Create a new spreadsheet file"));5 connect(newAction, SIGNAL(triggered()), this, SLOT(newFile()));
● Criando um action:
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 82
Lab5: Main Windows
1 QMenu *fileMenu = menuBar()->addMenu(tr("&File"));2 fileMenu->addAction(newAction);3 fileMenu->addAction(openAction);4 fileMenu->addAction(saveAction);5 fileMenu->addAction(saveAsAction);
● Inserindo actions em menus
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 83
Lab5: Main Windows
1 QToolBar *fileToolBar = addToolBar(tr("&File"));2 fileToolBar->addAction(newAction);3 fileToolBar->addAction(openAction);4 fileToolBar->addAction(saveAction);5 QToolBar *editToolBar = addToolBar(tr("&Edit"));6 editToolBar->addAction(cutAction);7 editToolBar->addSeparator();8 editToolBar->addAction(findAction);
● Inserindo actions em toolbars
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 84
Lab5: Main Windows
1 QLabel *locationLabel = new QLabel(" W999 ");2 QLabel *formulaLabel = new QLabel;3 statusBar()->addWidget(locationLabel);4 statusBar()->addWidget(formulaLabel, 1);5 connect(spreadsheet, SIGNAL(currentCellChanged(int, int, int, int)),6 this, SLOT(updateStatusBar()));7 connect(spreadsheet, SIGNAL(modified()),8 this, SLOT(spreadsheetModified()));9 updateStatusBar();
● Criando a barra de status
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 85
Lab5: Main Windows
1 int r = QMessageBox::warning(this, tr("Spreadsheet"),2 tr("The document has been modified.\n"3 "Do you want to save your changes?"),4 QMessageBox::Yes | QMessageBox::Default,5 QMessageBox::No,6 QMessageBox::Cancel | QMessageBox::Escape);7 if (r == QMessageBox::Yes)8 return save();9 else10 if (r == QMessageBox::Cancel)11 return false;
● Usando um message box
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 86
Main Windows e Dialogs
● As imagens utilizadas pela aplicação (ícones etc) podem ser carregadas de três formas:● Através da leitura, em tempo de execução, dos
arquivos das imagens● Através da inclusão de imagens XPM no código-
fonte● Através do uso do mecanismo de resources do Qt
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 87
Main Windows e Dialogs
● Resources:● O arquivo de recursos de uma aplicação Qt indica
quais arquivos serão diretamente incluídos no executável a ser gerado. Dessa forma, ícones não são perdidos
● Na verdade, qualquer tipo de arquivo (não somente imagens) pode ser incluído no executável
● Arquivos de recursos podem ser organizados em categorias
● Recursos são utilizados com o prefixo “:/”
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 88
Lab6: Resources
● Utilizando resources ao invés de caminhos absolutos de ícones e imagens
● Dicas sobre actions:● Pode-se especificar aceleradores colocando o
caracter '&' antes do caracter acelerador● Pode-se especificar teclas de atalho na
propriedade shorcut● Pode-se especificar tips de toolbar e mensagens de
status nas propriedades toolTip e statusTip
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 89
Main Windows e Dialogs
Descrição XMLdo dialog oumainwindow(arquivo .ui)
UIC(User Interface
Compiler)
CódigoStandard C++
(classe no namespace Ui)
● Entendendo o Qt Designer
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 90
Main Windows e Dialogs
● Fluxo de trabalho no Qt Designer:● Crie a sua Main Window ou Dialog no Qt Designer● Crie uma nova classe derivando da classe base
correspondente e agregando a classe gerada a partir do Qt Designer
● Implemente a sua funcionalidade nesta classe recém-criada
● Isso garante a separação entre o código gerado pelo Qt Designer e o código que implementa a funcionalidade
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 91
Lab7: Funcionalidades
1 #include <QDialog>2 #include "ui_cdmainwindow.h"34 class CdMainWindow : public QMainWindow, public Ui::CdMainWindow5 {6 Q_OBJECT7 public:8 CdMainWindow(QWidget *parent = 0);9 private slots:10 void on_lineEdit_textChanged();11 };
● Implementando funcionalidade
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 92
Lab7: Funcionalidades
1 #include <QtGui>2 #include "cdmainwindow.h"34 CdMainWindow::CdMainWindow(QWidget *parent) : QmainWindow(parent)5 {6 setupUi(this);7 QRegExp regExp("[A-Za-z][1-9][0-9]{0,2}");8 lineEdit->setValidator(new QRegExpValidator(regExp, this));9 }1011 void CdMainWindow::on_lineEdit_textChanged()12 {13 okButton->setEnabled(lineEdit->hasAcceptableInput());14 }
● Implementando funcionalidade
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 93
Lab7: Funcionalidades
1 #include <QApplication>2 #include "cdmainwindow.h"3 int main(int argc, char *argv[])4 {5 QApplication app(argc, argv);6 CdMainWindow *mw = new CdMainWindow;7 mw->show();8 return app.exec();9 }
● Implementando funcionalidade
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 94
Lab7: Funcionalidades
1 MainWindow::MainWindow(...)2 {3 ...4 findDialog = 0;5 ...6 }78 void MainWindow::on_findAction_triggered()9 {10 if (!findDialog)11 {12 findDialog = new FindDialog(this);13 }14 findDialog->show();15 findDialog->activateWindow();16 }
● Usando modeless dialogs
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 95
Lab7: Funcionalidades
1 void MainWindow::addCd()2 {3 AddCdDialog addCdDialog(this);4 if (addCdDialog.exec())5 {6 // Retorna QDialog::Accepted ou QDialog::Reject7 ...8 }9 }
● Usando modal dialogs
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 96
Lab8: Aplicações MDI
● Aplicações MDI (Multiple Document Interface)● Criadas utilizando uma instância de QMdiArea
como centralWidget de uma Main Window● Novas janelas são adicionadas usando
addSubWindow()
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 97
Main Windows e Dialogs
● Size policies: especificam como o widget será alterado pelo layout manager:● Fixed: o widget não pode aumentar ou diminuir.
Será sempre mantido no seu tamanho atual● Minimum: o tamanho atual é o tamanho mínimo do
widget● Maximum: o tamanho atual é o tamanho máximo
do widget● Preferred: o tamanho atual é o preferido, mas ele
podem aumentar ou diminuir● Expanding: o widget é propenso a aumentar
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 98
Main Windows e Dialogs
● Size policies
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 99
Criando Novos Widgets
● Novos widgets podem ser criados herdando a classe QWidget e reimplementando a função paint()
● A função paint() é automaticamente chamada sempre que o widget precisa ser (re)desenhado
● As funções de desenho estão concentradas na classe QPainter
● O QPainter suporta operações de rotação, translação e escala
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 100
Criando Novos Widgets
● Sistema de painting
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 101
Lab9: Widget Relógio
1 void AnalogClock::paintEvent(QPaintEvent *)2 {3 static const QPoint hourHand[3] = {4 QPoint(7, 8), QPoint(-7, 8), QPoint(0, -40)5 };6 static const QPoint minuteHand[3] = {7 QPoint(7, 8), QPoint(-7, 8), QPoint(0, -70)8 };910 QColor hourColor(127, 0, 127);11 QColor minuteColor(0, 127, 127, 191);1213 int side = qMin(width(), height());14 QTime time = QTime::currentTime();
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 102
Lab9: Widget Relógio
1 QPainter painter(this);2 painter.setRenderHint(QPainter::Antialiasing);3 painter.translate(width() / 2, height() / 2);4 painter.scale(side / 200.0, side / 200.0);56 painter.setPen(Qt::NoPen);7 painter.setBrush(hourColor);89 painter.save();10 painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));11 painter.drawConvexPolygon(hourHand, 3);12 painter.restore();1314 painter.setPen(hourColor);1516 for (int i = 0; i < 12; ++i) {17 painter.drawLine(88, 0, 96, 0);18 painter.rotate(30.0);19 }
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 103
Lab9: Widget Relógio
1 painter.setPen(Qt::NoPen);2 painter.setBrush(minuteColor);34 painter.save();5 painter.rotate(6.0 * (time.minute() + time.second() / 60.0));6 painter.drawConvexPolygon(minuteHand, 3);7 painter.restore();89 painter.setPen(minuteColor);1011 for (int j = 0; j < 60; ++j) {12 if ((j % 5) != 0)13 painter.drawLine(92, 0, 96, 0);14 painter.rotate(6.0);15 }16 }
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 104
Model View
● Muitas aplicações permitem a busca, visualização e edição de itens individuais de um conjunto de dados
● Em versões anteriores do Qt, os widgets eram populados com todo o conteúdo do conjunto de dados, estes eram alterados e posteriormente atualizados na sua origem
● Entretanto, esta abordagem não é escalável para grandes conjuntos e não resolve o problema da visualização do mesmo conjunto ou dois ou mais widgets diferentes
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 105
Model View
● O Qt4 usa o padrão Model View, uma variação do model-view-controller, para resolver esses problemas:
– Model: representa o conjunto de dados e é responsável pela aquisição e atualização de dados a partir da origem. Cada tipo de dados tem seu próprio modelo, porém a API provida pelos modelos aos views é padrão
– View: apresenta os dados para o usuário. Para grandes conjuntos, exibe somente o necessário (lazy-load)
– Controller: mediador entre o usuário e o view. Converte ações do usuário em requisições para navegar e editar dados, os quais são enviados pelo view para o model
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 106
Model View
● Qt4 Model View
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 107
Model View
● Qt4 Model View● O delegate é usado para ter total controle sobre
como os itens são apresentados e editados● O Qt disponibiliza um delegate padrão para cada
tipo de view● Os modelos podem obter somente os dados que
são realmente necessários● Cada item de dados em um modelo é representado
por um index● O Qt traz um conjunto de modelos e outros podem
ser criados
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 108
Model View
● Os widgets são divididos em dois grupos:● As classes QListWidget, QTableWidget e
QTreeWidget devem ser utilizadas para apresentar poucos itens
● Para grandes conjuntos devem ser utilizadas as classes QListView, QTableView e QTreeView, em conjunto com um modelo de dados (do Qt ou customizado)
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 109
Model View
● Modelos predefinidos do Qt:– QStringListModel: armazena uma lista de strings– QStandardItemModel: armazena dados hierárquicos
arbitrários– QFileSystemModel: encapsula o sistema de arquivos
local– QSqlQueryModel: encapsula um resultset SQL– QSqlTableModel: encapsula uma tabela SQL– QSqlRelationalTableModel: encapsula uma tabela SQL
com chaves estrangeiras– QSortFilterProxyModel: ordena ou filtra outro modelo
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 110
Lab10: Model View
1 QFileSystemModel *model = new QFileSystemModel;2 model->setRootPath(QDir::currentPath());34 QTreeView *tree = new QTreeView(splitter);5 tree->setModel(model);6 tree->setRootIndex(model->index(QDir::currentPath()));78 QListView *list = new QListView(splitter);9 list->setModel(model);10 list->setRootIndex(model->index(QDir::currentPath()));
● Visualizando o sistema de arquivos
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 111
Model View
● Entendendo as classes de modelo
● Índice = linha + coluna + índice pai● Roles
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 112
Lab11: Delegates
1 class SpinBoxDelegate : public QItemDelegate2 {3 Q_OBJECT4 public:5 SpinBoxDelegate(QObject *parent = 0);6 QWidget *createEditor(QWidget *parent,
const QStyleOptionViewItem &option, const QModelIndex &index) const;
7 void setEditorData(QWidget *editor,const QModelIndex &index) const;
8 void setModelData(QWidget *editor, QAbstractItemModel *model,9 const QModelIndex &index) const;10 void updateEditorGeometry(QWidget *editor,11 const QStyleOptionViewItem &option,
const QModelIndex &index) const;12 };
● Utilizando outros delegates
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 113
Lab11: Delegates
1 QWidget *SpinBoxDelegate::createEditor(QWidget *parent,2 const QStyleOptionViewItem &/* option */,3 const QModelIndex &/* index */) const4 {5 QSpinBox *editor = new QSpinBox(parent);6 editor->setMinimum(0);7 editor->setMaximum(100);89 return editor;10 }1112 void SpinBoxDelegate::setEditorData(QWidget *editor,13 const QModelIndex &index) const14 {15 int value = index.model()->data(index, Qt::EditRole).toInt();16 QSpinBox *spinBox = static_cast<QSpinBox*>(editor);17 spinBox->setValue(value);18 }
● Utilizando outros delegates
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 114
Lab11: Delegates
1 void SpinBoxDelegate::setModelData(QWidget *editor,QAbstractItemModel *model,
2 const QModelIndex &index) const3 {4 QSpinBox *spinBox = static_cast<QSpinBox*>(editor);5 spinBox->interpretText();6 int value = spinBox->value();7 model->setData(index, value, Qt::EditRole);8 }910 void SpinBoxDelegate::updateEditorGeometry(QWidget *editor,11 const QStyleOptionViewItem &option,
const QModelIndex &/* index */) const12 {13 editor->setGeometry(option.rect);14 }
● Utilizando outros delegates
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 115
Generic Containers
● Classes template de propósito geral para armazenamento de outros objetos
● São implicitamente compartilhados, reentrantes, com bom desempenho e baixo consumo de memória e são thread-safe se utilizados somente de forma read-only
● Possuem dois tipos de iterators:● Java-style: fáceis de usar● STL-style: ligeiramente mais eficientes
● Foreach
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 116
Generic Containers
● São implicitamente compartilhados● Podem ser serializados com o QDataStream● Resultam em menos código executável que os
correspondentes STL● Containers sequenciais: QList, QLinkedList,
QVector, QStack e QQueue● Containers associativos: QMap, QMultiMap,
QHash, QMultiHash e QSet● Algoritmos genéricos. Ex: qSort(), qBinaryFind(),
qSwap()
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 117
Generic Containers
● Visão Geral:– QList:
● Implementada usando arrays, acesso rápido por índices, expansão mínima de código no executável
– QLinkedList:● Implementada como lista encadeada, melhor desempenho para
inserções no meio, melhor semântica de iterators
– QVector:● Implementado usando arrays, inserções no início e no meio são
custosas
– QStack:● Sub-classe conveniente de QVector com semântica LIFO
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 118
Generic Containers
● Visão Geral:– QQueue:
● Sub-classe conveniente de QList com semântica FIFO
– QSet:● Representa conjuntos matemática com acessos rápidos
– Q[Multi]Map:● Dicionário que mapeia chaves em valores, armazena os dados
ordenados pela chave
– Q[Multi]Hash:● Armazena os dados em ordem arbitrário, acesso mais rápido
que o Q[Multi]Map
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 119
Generic Containers
● Iterators
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 120
Generic Containers
1 QList<QString> list;2 list << "A" << "B" << "C" << "D";34 QListIterator<QString> i(list);5 while (i.hasNext())6 qDebug() << i.next();789 QListIterator<QString> i(list);10 i.toBack();11 while (i.hasPrevious())12 qDebug() << i.previous();
● Iterators Java-style
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 121
Generic Containers
1 QMutableListIterator<int> i(list);2 while (i.hasNext()) {3 if (i.next() % 2 != 0)4 i.remove();5 }678 QMutableListIterator<int> i(list);9 while (i.hasNext()) {10 if (i.next() > 128)11 i.setValue(128);12 }
● Iterators com suporte a modificações
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 122
Generic Containers
1 QList<QString> list;2 list << "A" << "B" << "C" << "D";34 QList<QString>::iterator i;5 for (i = list.begin(); i != list.end(); ++i)6 *i = (*i).toLower();
● Iterators STL-style
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 123
Generic Containers
1 QLinkedList<QString> list;2 foreach (QString str, list) {3 if (str.isEmpty())4 break;5 qDebug() << str;6 }78 QMap<QString, int> map;9 foreach (QString str, map.keys())10 qDebug() << str << ":" << map.value(str);1112 QMultiMap<QString, int> map;13 foreach (QString str, map.uniqueKeys()) {14 foreach (int i, map.values(str))15 qDebug() << str << ":" << i;16 }
● Foreach
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 124
Generic Containers
● Complexidades:
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 125
Entrada e Saida (E/S)
● O Qt disponibiliza duas classes principais para operações de entrada e saida:● QTextStream: entrada e saida de dados texto● QDataStream: entrada e saida de dados binários
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 126
Entrada e Saida (E/S)
1 QFile data("output.txt");2 if (data.open(QFile::WriteOnly | QFile::Truncate)) {3 QTextStream out(&data);4 out << "Result: " << qSetFieldWidth(10) << left << 3.14 << 2.7;5 // writes "Result: 3.14 2.7 "6 }789 QTextStream in("0x50 0x20");10 int firstNumber, secondNumber;1112 in >> firstNumber; // firstNumber == 8013 in >> dec >> secondNumber; // secondNumber == 01415 char ch;16 in >> ch; // ch == 'x'
● Gravando e recuperando dados texto
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 127
Entrada e Saida (E/S)
● Manipuladores
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 128
Entrada e Saida (E/S)
1 QFile file("file.dat");2 file.open(QIODevice::WriteOnly);3 QDataStream out(&file); // we will serialize the data into the file4 out << QString("the answer is"); // serialize a string5 out << (qint32)42; // serialize an integer678 QFile file("file.dat");9 file.open(QIODevice::ReadOnly);10 QDataStream in(&file); // read the data serialized from the file11 QString str;12 qint32 a;13 in >> str >> a; // extract "the answer is" and 42
● Gravando e recuperando dados binário
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 129
Entrada e Saida (E/S)
1 QDataStream &operator<<(QDataStream &, const QXxx &);2 QDataStream &operator>>(QDataStream &, QXxx &);
● Uma série de classes Qt já suportam entrada e saida via QDataStream, inclusive os containers
● Pode-se adicionar este suporte em novas classes através da implementação dos operadores << e >>
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 130
Lab12: Containers e E/S
● Containers aninhados● Gravação e recuperação usando QDataStream
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 131
Banco de Dados
● O módulo QtSql disponibiliza uma interface independente de plataforma e de banco de dados
● Essa interface é suportada por um conjunto de classes que usam a arquitetura Model View do Qt
● Uma conexão de banco é representada por uma instância da classe QSqlDatabase
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 132
Banco de Dados
● Drivers disponíveis:– QMYSQL: MySQL >= 4– QOCI: Oracle Call Interface– QODBC: Open Database Connectivity– QPSQL: PostgreSQL >= 7.3– QTDS: Sybase Adaptive Server– QDB2: IBM DB2 >= 7.1– QSQLITE2: SQLite v2– QSQLITE: SQLite >= 3– QIBASE: Borland Interbase
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 133
Banco de Dados
● O banco pode ser utilizado de duas formas:● Com a classe QSqlQuery é possível a execução
direta de sentenças SQL● Com classes de mais alto nível como
QSqlTableModel e QsqlRelationalTableModel
● As classes de mais alto nível podem ser anexadas a widgets para visualização automática dos dados do banco
● O Qt torna fácil a programação de recursos como master-detail e drill-down
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 134
Banco de Dados
1 inline bool createConnection()2 {3 QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");4 db.setDatabaseName("cddatabase.db");5 if (!db.open())6 {7 QMessageBox::warning(0, QObject::tr("Database Error"),8 db.lastError().text());9 return false;10 }11 return true;12 }
● Criando a conexão default
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 135
Banco de Dados
1 QSqlQuery query;2 query.exec("SELECT title, year FROM cd WHERE year >= 1998");3 while (query.next())4 {5 QString title = query.value(0).toString();6 int year = query.value(1).toInt();7 qDebug() << title << ": " << year << endl;8 }
● Executando sentenças SQL
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 136
Banco de Dados
1 QSqlQuery query;23 query.exec("CREATE TABLE artist (id INTEGER PRIMARY KEY, "4 "name VARCHAR(40) NOT NULL, country VARCHAR(40))");56 query.exec("CREATE TABLE cd (id INTEGER PRIMARY KEY, "7 "title VARCHAR(40) NOT NULL, artistid INTEGER NOT NULL, "8 "year INTEGER NOT NULL, "9 "FOREIGN KEY (artistid) REFERENCES artist)");1011 query.exec("CREATE TABLE track (id INTEGER PRIMARY KEY, "12 "title VARCHAR(40) NOT NULL, duration INTEGER NOT NULL, "13 "cdid INTEGER NOT NULL)");
● QSqlQuery pode ser utilizado com comandos DDL e inserts
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 137
Banco de Dados
1 QSqlTableModel model;2 model.setTable("cd");3 model.setFilter("year >= 1998");4 model.select();5 connect(model, SIGNAL(beforeInsert(QSqlRecord &)),6 this, SLOT(beforeInsertArtist(QSqlRecord &)));7 for (int i = 0; i < model.rowCount(); ++i)8 {9 QSqlRecord record = model.record(i);10 QString title = record.value("title").toString();11 int year = record.value("year").toInt();12 qDebug() << title << ": " << year << endl;13 }
● Consultando com QSqlTableModel
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 138
Banco de Dados
1 model = new QSqlTableModel(this);2 model->setTable("artist");3 model->setSort(Artist_Name, Qt::AscendingOrder);4 model->setHeaderData(Artist_Id, Qt::Horizontal, tr("Id"));5 model->setHeaderData(Artist_Name, Qt::Horizontal, tr("Name"));6 model->setHeaderData(Artist_Country, Qt::Horizontal, tr("Country"));7 model->select();8 artistTableView = new QTableView;9 artistTableView->setModel(model);10 artistTableView->setSelectionBehavior(QAbstractItemView::SelectRows);11 artistTableView->resizeColumnsToContents();
● Ligando o model a uma view
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 139
Banco de Dados
1 ...2 connect(model, SIGNAL(beforeInsert(QSqlRecord &)),3 this, SLOT(beforeInsertArtist(QSqlRecord &)));4 ...56 int row = model->rowCount();7 model->insertRow(row);8 QModelIndex index = model->index(row, Artist_Name);9 tableView->setCurrentIndex(index);10 tableView->edit(index);11 …1213 void ArtistForm::beforeInsertArtist(QSqlRecord &record)14 {15 record.setValue("id", generateId("artist"));16 }
● Incluindo registros
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 140
Banco de Dados
1 inline int generateId(const QString &table)2 {3 QSqlQuery query;4 query.exec("SELECT MAX(id) FROM " + table);5 int id = 0;6 if (query.next())7 id = query.value(0).toInt() + 1;8 return id;9 }
● Incluindo registros
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 141
Banco de Dados
1 tableView->setFocus();2 QModelIndex index = tableView->currentIndex();3 if (!index.isValid()) return;4 QSqlRecord record = model->record(index.row());5 QSqlTableModel cdModel;6 cdModel.setTable("cd");7 cdModel.setFilter("artistid = " + record.value("id").toString());8 cdModel.select();9 if (cdModel.rowCount() == 0) {10 model->removeRow(tableView->currentIndex().row());11 } else {12 QMessageBox::information(this,13 tr("Delete Artist"),14 tr("Cannot delete %1 because there are CDs associated "15 "with this artist in the collection.")16 .arg(record.value("name").toString()));17 }
● Excluindo registros
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 142
Lab13: Banco de Dados
● Uso da classe QSqlQuery● Integração com o Model View● Inclusão e Exclusão
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 143
Banco de Dados
1 connect(cdTableView->selectionModel(),2 SIGNAL(currentRowChanged(const QModelIndex &,3 const QModelIndex &)),4 this,5 SLOT(currentCdChanged(const QModelIndex &)));
● Relacionamentos e master-detail– Para o detail usa-se o QSqlTableModel original com
um filtro– Para o master usar o QSqlRelationalTableModel– Capturar o signal currentRowChanged do modelo
master para atualizar o detail
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 144
Lab14: Master-Detail
● Configuração da base de dados● QSqlRelationalTableModel● QSqlTableModel
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 145
Graphics View
● Promove o gerenciamento de uma grande quantidade de itens gráficos 2D e disponibiliza um widget para visualização destes itens com suporte a zomming e rotação
● Surgiu no Qt 4.2 substituindo o QCanvas● Promove uma abordagem baseada em itens
para o estilo Model View● Várias views podem observar uma cena e uma
cena contém itens de várias formas geométricas
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 146
Graphics View
● Arquitetura:– Cena:
● Provê interface rápida para manipulação uma quantidade grande de itens
● Propaga eventos para cada item● Gerencia o estado do item, como seleção e foco● Provê funcionalidades de rendering sem transformações
– View:● Visualiza o conteúdo da cena● Recebe eventos de teclado e mouse e os traduz para eventos
de cena● Pode transformar o sistema de coordenadas de cena● Se não transformada visualiza uma unidade da cena como um
pixel na view
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 147
Graphics View
● Arquitetura:– Item:
● QGraphicsItem é a classe base de todos os itens● O Qt disponibiliza itens padrão para as primitivas básicas● Você pode desenvolver o seu próprio item● Suporte aos eventos de teclado e mouse● Drag and drop● Relacionamento através de parentesco e agrupamento● Detecção de colisão através da função shape() e collidsWith()● É definido no seu sistema de coordenadas local● Podem sofrer transformações locais, repassando-as para os
filhos
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 148
Graphics View
● Arquitetura:– Itens pré-definidos no Qt
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 149
Graphics View
● Sistemas de Coordenadas:– Coordenadas de item, de cena e de view– Funções de conveniência permitem fazer a conversão:
● Que item foi clicado ?– QGraphicsView::mapToScene() + QGraphicsScene::itemAt()
● Onde no view o item está localizado ?– QGraphicsItem::mapToScene() +
QGraphicsView::mapFromScene()● Quais itens estão dentro de uma elipse na view ?
– Passe um QPainterPath para QGraphicsView::mapToScene() + QGraphicsScene::itens()
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 150
Graphics View
1 class View : public QGraphicsView2 {3 Q_OBJECT4 ...5 public slots:6 void zoomIn() { scale(1.2, 1.2); }7 void zoomOut() { scale(1 / 1.2, 1 / 1.2); }8 void rotateLeft() { rotate(-10); }9 void rotateRight() { rotate(10); }10 ...11 };
● Implementando zoom e rotação
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 151
Lab15: Coordenadas
1 QGraphicsScene scene;2 QGraphicsRectItem *rect = scene.addRect(QRectF(0, 0, 100, 100));34 QGraphicsItem *item = scene.itemAt(50, 50);5 // item == rect67 QGraphicsScene scene;8 myPopulateScene(&scene);910 QGraphicsView view(&scene);11 view.show();
● Implementar seleção de itens e operações
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 152
Lab16: Novos Itens
1 class SimpleItem : public QGraphicsItem2 {3 public:4 QRectF boundingRect() const5 {6 qreal penWidth = 1;7 return QRectF(-10 - penWidth / 2, -10 - penWidth / 2,8 20 + penWidth, 20 + penWidth);9 }1011 void paint(QPainter *painter,
const QStyleOptionGraphicsItem *option, QWidget *widget)12 {13 painter->drawRoundedRect(-10, -10, 20, 20, 5, 5);14 }15 };
● Implementando novos itens
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 153
XML
● O Módulo QtXml disponibiliza duas interfaces para manipulação de XML:● SAX (Simple API for XML): reporta eventos de
parsing diretamente para a aplicação, pouco consumo de memória, não suporta navegação na estrutura
● DOM (Document Object Model): converte um documento XML em uma árvore de objetos, na qual a aplicação pode navegar. Mantém a estrutura em memória
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 154
XML
● Lendo XML com o SAX● O Qt disponibiliza a classe QXmlSimpleReader
para a leitura não validada de documentos XML● Funções virtuais de objetos handler registrados são
invocadas para sinalizar os eventos
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 155
XML
1 <doc>2 <quote>Ars longa vita brevis</quote>3 </doc>
1 startDocument()2 startElement("doc")3 startElement("quote")4 characters("Ars longa vita brevis")5 endElement("quote")6 endElement("doc")7 endDocument()
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 156
Lab17: XML SAX
1 class SaxHandler : public QXmlDefaultHandler2 {3 public:4 SaxHandler(QTreeWidget *tree);5 bool startElement(const QString &namespaceURI,
const QString &localName, const QString &qName, const QXmlAttributes &attributes);
6 bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName);
7 bool characters(const QString &str);8 bool fatalError(const QXmlParseException &exception);910 private:11 QTreeWidget *treeWidget;12 };
● Exemplo de classe handler para o SAX
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 157
XML
1 bool parseFile(const QString &fileName)2 {3 QFile file(fileName);4 QXmlInputSource inputSource(&file);5 QXmlSimpleReader reader;6 SaxHandler handler(treeWidget);7 reader.setContentHandler(&handler);8 reader.setErrorHandler(&handler);9 return reader.parse(inputSource);10 }
● Processando o XML
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 158
XML
● Lendo XML com o DOM● Provê uma interface para acessar e modificar o
conteúdo e estrutura de um arquivo XML● Todos os nós da árvore do documento são
derivados de QDomNode
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 159
Lab18: XML DOM
1 QDomDocument doc("mydocument");2 QFile file("mydocument.xml");3 if (!file.open(QIODevice::ReadOnly))4 return;5 if (!doc.setContent(&file)) {6 file.close();7 return;8 }9 file.close();
● Lendo XML com o DOM
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 160
Lab18: XML DOM
10 QDomElement docElem = doc.documentElement();1112 QDomNode n = docElem.firstChild();13 while(!n.isNull()) {14 QDomElement e = n.toElement();15 if(!e.isNull()) {16 cout << qPrintable(e.tagName()) << endl;17 }18 n = n.nextSibling();19 }2021 QDomElement elem = doc.createElement("img");22 elem.setAttribute("src", "myimage.png");23 docElem.appendChild(elem);
● Lendo XML com o DOM
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 161
XML
● A partir da versão 4.3 do Qt, as classes QXmlStreamReader e QXmlStreamWriter simplificam este processo
● O módulo QtXmlPatterns inclui o uso de XQuery e XPath para realizar buscas facilitadas em arquivos XML
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 162
Networking
● O Qt disponibiliza as classes QFtp e QHttp, que podem ser utilizadas para fazer download e upload de arquivos, bem como solicitar e receber páginas de servidores web
● O Qt também provê classes de nível mais baixo como QTcpSocket e QUdpSocket
● Para tratar conexões em servidores pode-se utilizar a classe QTcpServer
● Disponibiliza recursos para sockets seguros, certificados, chaves etc.
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 163
Lab19: Networking
1 QNetworkAccessManager *manager = new QNetworkAccessManager(this);2 connect(manager, SIGNAL(finished(QNetworkReply*)),3 this, SLOT(replyFinished(QNetworkReply*)));45 manager->get(QNetworkRequest(QUrl("http://qt.nokia.com")));
● Usando o QNetworkAccessManager
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 164
Internacionalização
● O Qt suporta unicode, idiomas não derivados do Latin e escritos da direita para a esquerda
● O Qt torna fácil traduzir todo um sistema de um idioma para outro:
– Envolva toda string visível pelo usuário na macro tr()– Execute o comando lupdate para gerar o arquivo a ser
traduzido– Utilize o Qt Linguist para traduzir o arquivo– Execute o comando lrelease para gerar o arquivo
traduzido
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 165
Internacionalização
● Grande parte das aplicações carrega o arquivo de traduções no momento em que é iniciada, baseado nas configurações de locale do sistema
● O Qt também possibilita a troca, em tempo de execução, do idioma utilizado pelo sistema
● O Qt também permite a seleção de imagens (ícones, splashs etc) a depender do locale do sistema
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 166
Lab20: Internacionalização
1 int main(int argc, char *argv[])2 {3 QApplication app(argc, argv);4 QTranslator appTranslator;5 appTranslator.load("myapp_" + QLocale::system().name(),6 qApp->applicationDirPath());7 app.installTranslator(&appTranslator);8 ...9 return app.exec();10 }
● Carregando a tradução ao iniciar a aplicação
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 167
Multithreading
● O desenvolvimento de aplicações multithreading é importante para um melhor aproveitamento dos recursos da máquina e melhorias em aspectos ligados a escalabilidade e tempo de resposta
● O Qt disponibiliza duas API's para multithreading:● QThread e associados● QtConcurrent
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 168
Multithreading
1 class MyThread : public QThread2 {3 Q_OBJECT4 protected:5 void run();6 };78 void MyThread::run()9 {10 ...11 }1213 …14 MyThread t;15 t.start(); // dettach
● Definindo e criando uma nova thread
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 169
Multithreading
● Desenvolvimento multithreading frequentemente leva a condições de corrida
● Class Qt para sincronização de threads:● QMutex: lock mutualmente exclusivo● QReadWriteLock: lock que distingue entre acesso
para leitura e escrita● QSemaphore: generalização do QMutex para
proteger mais de um recurso● QWaitCondition: acorda outras threads quando
uma condição é atendida
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 170
Multithreading
● Reentrância e Thread-Safety:● Uma função thread-safe pode ser chamada
simultaneamente de múltiplas threads, mesmo quando as invocações usam dados compartilhados, pois todas as referências aos dados compartilhados são serializadas
● Uma função reentrante pode também ser chamada simultaneamente de múltiplas threads, mas somente se cada invocação usa seus próprios dados
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 171
Multithreading
1 class Counter2 {3 public:4 Counter() { n = 0; }56 void increment() { ++n; }7 void decrement() { --n; }8 int value() const { return n; }910 private:11 int n;12 };
● Classe reentrante porém não thread-safe
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 172
Lab21: Sincronizando
1 class Counter2 {3 public:4 Counter() { n = 0; }56 void increment() { QMutexLocker locker(&mutex); ++n; }7 void decrement() { QMutexLocker locker(&mutex); --n; }8 int value() const { QMutexLocker locker(&mutex); return n; }910 private:11 mutable QMutex mutex;12 int n;13 };
● Tornando a classe thread-safe
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 173
Lab22: QtConcurrent
1 // Instantiate the objects and connect to the finished signal.2 MyClass myObject;3 QFutureWatcher<int> watcher;4 connect(&watcher, SIGNAL(finished()),
&myObject, SLOT(handleFinished()));56 // Start the computation.7 QFuture<int> future = QtConcurrent::run(...);8 watcher.setFuture(future);
● Usando QtConcurrent
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 174
Plugins
● O que é um plugin ?● “É uma biblioteca dinâmica que implementa uma
interface particular, com o objetivo de prover funcionalidades extras.”; (C++ GUI Programming with Qt4)
● Não requer que seja previamente compilada e linkada à aplicação
● O Qt4 possui um conjunto próprio de interfaces de plugins para domínios tais como:● Formato de imagens, drivers de banco de dados,
estilos de widgets, codificação de texto etc.
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 175
Plugins
● É possível criar novos domínios de plugins, específicos para uma aplicação em particular
● O framework para plugins do Qt adiciona recursos de conveniência e segurança à classe QLibrary
● Para criar um plugin para os domínios já existentes do Qt precisa-se implementar duas classes:● Plugin Wrapper● Plugin Handler
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 176
Plugins
● É possível criar novos domínios de plugins, específicos para uma aplicação em particular
● O framework para plugins do Qt adiciona recursos de conveniência e segurança à classe QLibrary
● Para criar um plugin para os domínios já existentes do Qt precisa-se implementar duas classes:● Plugin Wrapper● Plugin Handler
Classe factory para criação de novos handlers
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 177
Plugins
● É possível criar novos domínios de plugins, específicos para uma aplicação em particular
● O framework para plugins do Qt adiciona recursos de conveniência e segurança à classe QLibrary
● Para criar um plugin para os domínios já existentes do Qt precisa-se implementar duas classes:● Plugin Wrapper● Plugin Handler
Classe queefetivamente implementa a
funcionalidade
Classe factory para criação de novos handlers
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 178
Plugins
● Estas duas classes deverão ser filhas de classes disponibilizadas pelo Qt
Wrapper Handler
QAccessibleBridgePlugin QAccessibleBridgeQAccessiblePlugin QAccessibleInterfaceQIconEnginePlugin QIconEngineQImageIOPlugin QImageIOHandlerQInputContextPlugin QInputContextQPictureFormatPlugin -QSqlDriverPlugin QSqlDriverQStylePlugin QStyleQTextCodecPlugin QTextCodec
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 179
Plugins
● Os plugins para os domínios do Qt são invocados pelos próprios objetos do Qt (ex: QImageReader, QImageWriter)
● Plugins instalados globalmente devem estar localizados no diretório $QTDIR/plugins/
● Plugins instalados localmente devem estar no subdiretório plugins/ do diretório que contém o executável da aplicação
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 180
Plugins
● A arquitetura de plugins do Qt é uma abordagem interessante para a extensão facilitada de aplicações em C++
● As classes QLibrary e QPluginLoader do Qt realizam o processo de carga dinâmica de novas classes
● Se as interfaces dos plugins forem bem projetadas, pode-se estender aplicações sem requerer novas recompilações
● Alternativas: QtScript, Kross ...
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 181
Lab23: Plugins
● Definição de uma interface da aplicação● Implementação de dois plugins● Carga dos plugins no início da aplicação
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 182
Lab24: Qt Mobile
● O NOKIA Qt SDK torna o processo substancialmente mais fácil
● API's específicas para mobile
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 183
Conclusão
● Crescente expansão do Qt na indústria● O Qt está cada dia mais open source● O KDE melhora o Qt ainda mais● Programas:
● Qt in Education● NOKIA Qt Certification● Qt Dev Days● Akademy● Akademy-BR
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 184
FIM
Desenvolvimento
Cross-Platform com C++ e Qt
Sandro Santos Andrade