Desenvolvimento Cross-Platform com C++ e Qt
Transcrição
Desenvolvimento Cross-Platform com C++ e Qt
Desenvolvimento Cross-Platform com C++ e Qt Sandro Santos Andrade [email protected] http://liveblue.wordpress.com 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 2 Pré-requisitos ● Necessários: ● Fundamentos de Orientação a Objetos (OO) ● Experiência com alguma linguagem OO ● ● Desejáveis: ● ● Experiência com desenvolvimento de aplicações visuais 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 3 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 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 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 6 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 7 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 8 Visão Geral ● Módulos e ferramentas Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 9 Visão Geral ● Widgets Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 10 Visão Geral ● Dialogs e Main Windows 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 ● Gráficos 2D 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 ● OpenGL 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 ● Scripting Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 21 Visão Geral ● Interfaces animadas Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 22 Visão Geral ● Model View Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 23 Visão Geral ● Banco de Dados Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 24 Visão Geral ● Networking Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 25 Visão Geral ● XML Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 26 Visão Geral ● Ferramentas (Qt Designer) Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 27 Visão Geral ● Ferramentas (Qt Linguist) Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 28 Visão Geral ● Ferramentas (Qt Assistant) Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 29 Visão Geral ● Qt Mobile 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 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 33 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 34 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 35 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 36 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 37 Porque o Qt ? ● Quem usa o Qt ? Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 38 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 39 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 40 Lab1: Hello Qt 1 2 3 4 5 6 7 8 9 10 ● #include <QApplication> #include <QLabel> int main(int argc, char *argv[]) { QApplication app(argc, argv); QLabel *label = new QLabel("Hello Qt!"); label->show(); return app.exec(); } Executar: $ qmake -project $ qmake $ make Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 41 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 42 Lab1: Hello Qt ● O qmake: Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 43 Lab1: Hello Qt ● O qmake: ● 1 2 3 4 5 6 7 8 9 10 11 Arquivo de projeto automaticamente gerado neste exemplo ################################################################### # Automatically generated by qmake (2.01a) qua jul 21 22:43:25 2010 ################################################################### TEMPLATE = app TARGET = DEPENDPATH += . INCLUDEPATH += . # Input SOURCES += main.cpp Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 44 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 45 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 46 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 47 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 48 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 49 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 50 Signals / Slots ● ● 1 2 3 4 5 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: bool QObject::connect(senderqobjptr, SIGNAL(signalname(argtypelist)), receiverqobjptr, SLOT(slotname(argtypelist)) optionalConnectionType); Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 51 Signals / Slots Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 52 Lab2: Signals / Slots ● 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Um exemplo simples: #include <QObject> class Counter : public QObject { Q_OBJECT public: Counter() { m_value = 0; } int value() const { return m_value; } public slots: void setValue(int value); signals: void valueChanged(int newValue); private: int m_value; }; Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 53 Lab2: Signals / Slots ● 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Um exemplo simples: void Counter::setValue(int value) { if (value != m_value) { m_value = value; emit valueChanged(value); } } Counter a, b; QObject::connect(&a, SIGNAL(valueChanged(int)), &b, SLOT(setValue(int))); a.setValue(12); b.setValue(48); // a.value() == 12, b.value() == 12 // a.value() == 12, b.value() == 48 Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 54 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 55 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 56 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 57 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 (MetaObject 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 58 Signals / Slots ● Como signals e slots são implementados ? ● O MOC (Meta-Object Compiler) Código com extensões do Qt Ex: Q_OBJECT public slots: MOC (Meta-Object Compiler) Código Standard C++ Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 59 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 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: QWidget (top-level window) 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) QSlider (filho do QWidget) 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) QSpinBox (filho do QWidget) QSlider (filho do QWidget) Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 63 Layout e Parentesco ● Tipos de layout: – QHBoxLayout – QVBoxLayout – Layouts dinâmicos e em fluxo QGridLayout QformLayout Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 64 Layout e Parentesco ● Conexão de signals e slots Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 65 Lab3: Layout e Parentesco 1 2 3 4 #include #include #include #include <QApplication> <QHBoxLayout> <QSlider> <QSpinBox> 15 QObject::connect(spinBox, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int))); QObject::connect(slider, SIGNAL(valueChanged(int)), spinBox, SLOT(setValue(int))); spinBox->setValue(35); QHBoxLayout *layout = new QHBoxLayout; layout->addWidget(spinBox); layout->addWidget(slider); window->setLayout(layout); window->show(); return app.exec(); 19 5 6 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); 20 21 22 23 24 25 26 27 } Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 66 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 67 Lab3: Layout e Parentesco ● Hierarquia das classes utilizadas: Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 68 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/enus/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 69 Qt Reference Documentation ● http://doc.qt.nokia.com/4.6/ Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 70 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 71 Main Windows e Dialogs ● Layout e relações de parentesco: Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 72 Main Windows e Dialogs ● Dialogs pré-existentes no Qt: 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 Lab4: Dialogs 1 2 3 4 5 6 7 8 9 10 11 12 #include <QDialog> 15 class class class class QCheckBox; QLabel; QLineEdit; QPushButton; class FindDialog : public QDialog { Q_OBJECT public: FindDialog (QWidget *parent = 0); 13 signals: 14 void findNext( const QString &str, Qt::CaseSensitivity cs); 16 17 18 19 20 21 22 23 24 25 26 void findPrevious( const QString &str, Qt::CaseSensitivity cs); private slots: void findClicked(); void enableFindButton( const QString &text); private: QLabel *label; QLineEdit *lineEdit; QCheckBox *caseCheckBox; QCheckBox *backwardCheckBox; QPushButton *findButton; QPushButton *closeButton; }; Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 75 Lab4: Dialogs 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <QtGui> #include "finddialog.h" FindDialog::FindDialog( QWidget *parent) : QDialog(parent) { label = new QLabel( tr("Find &what:")); lineEdit = new QLineEdit; label->setBuddy(lineEdit); 15 16 17 18 19 20 caseCheckBox = new QCheckBox(tr("Match &case")); 21 22 backwardCheckBox = new QCheckBox( tr("Search &backward")); 23 24 findButton = new QPushButton(tr("&Find")); 25 findButton->setDefault(true); findButton->setEnabled(false); closeButton = new QPushButton(tr("Close")); connect(lineEdit, SIGNAL(textChanged( const QString &)), this, SLOT(enableFindButton( const QString &))); connect(findButton, SIGNAL(clicked()), this, SLOT(findClicked())); connect(closeButton, SIGNAL(clicked()), this, SLOT(close())); Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 76 Lab4: Dialogs 26 27 28 29 30 31 32 33 34 35 36 37 38 QHBoxLayout *topLeftLayout = new QHBoxLayout; topLeftLayout->addWidget(label); topLeftLayout->addWidget( lineEdit); QVBoxLayout *leftLayout = new QVBoxLayout; leftLayout>addLayout( topLeftLayout); leftLayout->addWidget( caseCheckBox); leftLayout->addWidget( backwardCheckBox); QVBoxLayout *rightLayout = new QVBoxLayout; rightLayout->addWidget( findButton); rightLayout->addWidget( closeButton); rightLayout->addStretch(); 39 QHBoxLayout *mainLayout = new QHBoxLayout; mainLayout->addLayout( leftLayout); mainLayout->addLayout( rightLayout); setLayout(mainLayout); 40 41 42 43 44 45 46 47 setWindowTitle(tr("Find")); setFixedHeight( sizeHint().height()); } Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 77 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 78 Main Windows e Dialogs ● Áreas definidas pela QMainWindow Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 79 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 80 Lab5: Main Windows ● Criando um action: 1 2 3 4 5 QAction *newAction = new QAction(tr("&New"), this); newAction->setIcon(QIcon(":/images/new.png")); newAction->setShortcut(tr("Ctrl+N")); newAction->setStatusTip(tr("Create a new spreadsheet file")); connect(newAction, SIGNAL(triggered()), this, SLOT(newFile())); Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 81 Lab5: Main Windows ● Inserindo actions em menus 1 2 3 4 5 QMenu *fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(newAction); fileMenu->addAction(openAction); fileMenu->addAction(saveAction); fileMenu->addAction(saveAsAction); Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 82 Lab5: Main Windows ● Inserindo actions em toolbars 1 2 3 4 5 6 7 8 QToolBar *fileToolBar = addToolBar(tr("&File")); fileToolBar->addAction(newAction); fileToolBar->addAction(openAction); fileToolBar->addAction(saveAction); QToolBar *editToolBar = addToolBar(tr("&Edit")); editToolBar->addAction(cutAction); editToolBar->addSeparator(); editToolBar->addAction(findAction); Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 83 Lab5: Main Windows ● Criando a barra de status 1 2 3 4 5 6 7 8 9 QLabel *locationLabel = new QLabel(" W999 "); QLabel *formulaLabel = new QLabel; statusBar()->addWidget(locationLabel); statusBar()->addWidget(formulaLabel, 1); connect(spreadsheet, SIGNAL(currentCellChanged(int, int, int, int)), this, SLOT(updateStatusBar())); connect(spreadsheet, SIGNAL(modified()), this, SLOT(spreadsheetModified())); updateStatusBar(); Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 84 Lab5: Main Windows ● Usando um message box 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 else 10 if (r == QMessageBox::Cancel) 11 return false; Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 85 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ódigofonte Através do uso do mecanismo de resources do Qt Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 86 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 87 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 88 Main Windows e Dialogs ● Entendendo o Qt Designer Descrição XML do dialog ou mainwindow (arquivo .ui) UIC (User Interface Compiler) Código Standard C++ (classe no namespace Ui) Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 89 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 90 Lab7: Funcionalidades ● 1 2 3 4 5 6 7 8 9 10 11 Implementando funcionalidade #include <QDialog> #include "ui_cdmainwindow.h" class CdMainWindow : public QMainWindow, public Ui::CdMainWindow { Q_OBJECT public: CdMainWindow(QWidget *parent = 0); private slots: void on_lineEdit_textChanged(); }; Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 91 Lab7: Funcionalidades ● 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Implementando funcionalidade #include <QtGui> #include "cdmainwindow.h" CdMainWindow::CdMainWindow(QWidget *parent) : QmainWindow(parent) { setupUi(this); QRegExp regExp("[A-Za-z][1-9][0-9]{0,2}"); lineEdit->setValidator(new QRegExpValidator(regExp, this)); } void CdMainWindow::on_lineEdit_textChanged() { okButton->setEnabled(lineEdit->hasAcceptableInput()); } Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 92 Lab7: Funcionalidades ● Implementando funcionalidade 1 2 3 4 5 6 7 8 9 #include <QApplication> #include "cdmainwindow.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); CdMainWindow *mw = new CdMainWindow; mw->show(); return app.exec(); } Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 93 Lab7: Funcionalidades ● 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Usando modeless dialogs MainWindow::MainWindow(...) { ... findDialog = 0; ... } void MainWindow::on_findAction_triggered() { if (!findDialog) { findDialog = new FindDialog(this); } findDialog->show(); findDialog->activateWindow(); } Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 94 Lab7: Funcionalidades ● Usando modal dialogs 1 2 3 4 5 6 7 8 9 void MainWindow::addCd() { AddCdDialog addCdDialog(this); if (addCdDialog.exec()) { // Retorna QDialog::Accepted ou QDialog::Reject ... } } Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 95 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 96 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 97 Main Windows e Dialogs ● Size policies Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 98 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 99 Criando Novos Widgets ● Sistema de painting Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 100 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 }; 9 10 QColor hourColor(127, 0, 127); 11 QColor minuteColor(0, 127, 127, 191); 12 13 int side = qMin(width(), height()); 14 QTime time = QTime::currentTime(); Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 101 Lab9: Widget Relógio 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.translate(width() / 2, height() / 2); painter.scale(side / 200.0, side / 200.0); painter.setPen(Qt::NoPen); painter.setBrush(hourColor); painter.save(); painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0))); painter.drawConvexPolygon(hourHand, 3); painter.restore(); painter.setPen(hourColor); for (int i = 0; i < 12; ++i) { painter.drawLine(88, 0, 96, 0); painter.rotate(30.0); } Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 102 Lab9: Widget Relógio 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 } painter.setPen(Qt::NoPen); painter.setBrush(minuteColor); painter.save(); painter.rotate(6.0 * (time.minute() + time.second() / 60.0)); painter.drawConvexPolygon(minuteHand, 3); painter.restore(); painter.setPen(minuteColor); for (int j = 0; j < 60; ++j) { if ((j % 5) != 0) painter.drawLine(92, 0, 96, 0); painter.rotate(6.0); } Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 103 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 104 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 105 Model View ● Qt4 Model View Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 106 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 107 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 108 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 109 Lab10: Model View ● 1 2 3 4 5 6 7 8 9 10 Visualizando o sistema de arquivos QFileSystemModel *model = new QFileSystemModel; model->setRootPath(QDir::currentPath()); QTreeView *tree = new QTreeView(splitter); tree->setModel(model); tree->setRootIndex(model->index(QDir::currentPath())); QListView *list = new QListView(splitter); list->setModel(model); list->setRootIndex(model->index(QDir::currentPath())); Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 110 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 111 Lab11: Delegates ● Utilizando outros delegates 1 2 3 4 5 6 class SpinBoxDelegate : public QItemDelegate { Q_OBJECT public: SpinBoxDelegate(QObject *parent = 0); 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 }; Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 112 Lab11: Delegates ● 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Utilizando outros delegates QWidget *SpinBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/* option */, const QModelIndex &/* index */) const { QSpinBox *editor = new QSpinBox(parent); editor->setMinimum(0); editor->setMaximum(100); return editor; } void SpinBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { int value = index.model()->data(index, Qt::EditRole).toInt(); QSpinBox *spinBox = static_cast<QSpinBox*>(editor); spinBox->setValue(value); } Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 113 Lab11: Delegates ● 1 Utilizando outros delegates void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QSpinBox *spinBox = static_cast<QSpinBox*>(editor); spinBox->interpretText(); int value = spinBox->value(); model->setData(index, value, Qt::EditRole); } 2 3 4 5 6 7 8 9 10 void SpinBoxDelegate::updateEditorGeometry(QWidget *editor, 11 const QStyleOptionViewItem &option, const QModelIndex &/* index */) const 12 { 13 editor->setGeometry(option.rect); 14 } Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 114 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 115 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 116 Generic Containers ● Visão Geral: – QList: ● – QLinkedList: ● – Implementada como lista encadeada, melhor desempenho para inserções no meio, melhor semântica de iterators QVector: ● – Implementada usando arrays, acesso rápido por índices, expansão mínima de código no executável 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 117 Generic Containers ● Visão Geral: – QQueue: ● – QSet: ● – Representa conjuntos matemática com acessos rápidos Q[Multi]Map: ● – Sub-classe conveniente de QList com semântica FIFO 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 118 Generic Containers ● Iterators Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 119 Generic Containers ● 1 2 3 4 5 6 7 8 9 10 11 12 Iterators Java-style QList<QString> list; list << "A" << "B" << "C" << "D"; QListIterator<QString> i(list); while (i.hasNext()) qDebug() << i.next(); QListIterator<QString> i(list); i.toBack(); while (i.hasPrevious()) qDebug() << i.previous(); Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 120 Generic Containers ● 1 2 3 4 5 6 7 8 9 10 11 12 Iterators com suporte a modificações QMutableListIterator<int> i(list); while (i.hasNext()) { if (i.next() % 2 != 0) i.remove(); } QMutableListIterator<int> i(list); while (i.hasNext()) { if (i.next() > 128) i.setValue(128); } Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 121 Generic Containers ● 1 2 3 4 5 6 Iterators STL-style QList<QString> list; list << "A" << "B" << "C" << "D"; QList<QString>::iterator i; for (i = list.begin(); i != list.end(); ++i) *i = (*i).toLower(); Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 122 Generic Containers ● 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Foreach QLinkedList<QString> list; foreach (QString str, list) { if (str.isEmpty()) break; qDebug() << str; } QMap<QString, int> map; foreach (QString str, map.keys()) qDebug() << str << ":" << map.value(str); QMultiMap<QString, int> map; foreach (QString str, map.uniqueKeys()) { foreach (int i, map.values(str)) qDebug() << str << ":" << i; } Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 123 Generic Containers ● Complexidades: Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 124 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 125 Entrada e Saida (E/S) ● 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Gravando e recuperando dados texto QFile data("output.txt"); if (data.open(QFile::WriteOnly | QFile::Truncate)) { QTextStream out(&data); out << "Result: " << qSetFieldWidth(10) << left << 3.14 << 2.7; // writes "Result: 3.14 2.7 " } QTextStream in("0x50 0x20"); int firstNumber, secondNumber; in >> firstNumber; in >> dec >> secondNumber; // firstNumber == 80 // secondNumber == 0 char ch; in >> ch; // ch == 'x' Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 126 Entrada e Saida (E/S) ● Manipuladores Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 127 Entrada e Saida (E/S) ● 1 2 3 4 5 6 7 8 9 10 11 12 13 Gravando e recuperando dados binário QFile file("file.dat"); file.open(QIODevice::WriteOnly); QDataStream out(&file); // we will serialize the data into the file out << QString("the answer is"); // serialize a string out << (qint32)42; // serialize an integer QFile file("file.dat"); file.open(QIODevice::ReadOnly); QDataStream in(&file); // read the data serialized from the file QString str; qint32 a; in >> str >> a; // extract "the answer is" and 42 Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 128 Entrada e Saida (E/S) ● ● 1 2 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 >> QDataStream &operator<<(QDataStream &, const QXxx &); QDataStream &operator>>(QDataStream &, QXxx &); Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 129 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 130 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 131 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 132 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 133 Banco de Dados ● Criando a conexão default 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 } Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 134 Banco de Dados ● 1 2 3 4 5 6 7 8 Executando sentenças SQL QSqlQuery query; query.exec("SELECT title, year FROM cd WHERE year >= 1998"); while (query.next()) { QString title = query.value(0).toString(); int year = query.value(1).toInt(); qDebug() << title << ": " << year << endl; } Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 135 Banco de Dados ● 1 2 3 4 5 6 7 8 9 10 11 12 13 QSqlQuery pode ser utilizado com comandos DDL e inserts QSqlQuery query; query.exec("CREATE TABLE artist (id INTEGER PRIMARY KEY, " "name VARCHAR(40) NOT NULL, country VARCHAR(40))"); query.exec("CREATE TABLE cd (id INTEGER PRIMARY KEY, " "title VARCHAR(40) NOT NULL, artistid INTEGER NOT NULL, " "year INTEGER NOT NULL, " "FOREIGN KEY (artistid) REFERENCES artist)"); query.exec("CREATE TABLE track (id INTEGER PRIMARY KEY, " "title VARCHAR(40) NOT NULL, duration INTEGER NOT NULL, " "cdid INTEGER NOT NULL)"); Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 136 Banco de Dados ● 1 2 3 4 5 6 7 8 9 10 11 12 13 Consultando com QSqlTableModel QSqlTableModel model; model.setTable("cd"); model.setFilter("year >= 1998"); model.select(); connect(model, SIGNAL(beforeInsert(QSqlRecord &)), this, SLOT(beforeInsertArtist(QSqlRecord &))); for (int i = 0; i < model.rowCount(); ++i) { QSqlRecord record = model.record(i); QString title = record.value("title").toString(); int year = record.value("year").toInt(); qDebug() << title << ": " << year << endl; } Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 137 Banco de Dados ● Ligando o model a uma view 1 2 3 4 5 6 7 8 9 10 11 model = new QSqlTableModel(this); model->setTable("artist"); model->setSort(Artist_Name, Qt::AscendingOrder); model->setHeaderData(Artist_Id, Qt::Horizontal, tr("Id")); model->setHeaderData(Artist_Name, Qt::Horizontal, tr("Name")); model->setHeaderData(Artist_Country, Qt::Horizontal, tr("Country")); model->select(); artistTableView = new QTableView; artistTableView->setModel(model); artistTableView->setSelectionBehavior(QAbstractItemView::SelectRows); artistTableView->resizeColumnsToContents(); Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 138 Banco de Dados ● Incluindo registros 1 ... 2 connect(model, SIGNAL(beforeInsert(QSqlRecord &)), 3 this, SLOT(beforeInsertArtist(QSqlRecord &))); 4 ... 5 6 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 … 12 13 void ArtistForm::beforeInsertArtist(QSqlRecord &record) 14 { 15 record.setValue("id", generateId("artist")); 16 } Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 139 Banco de Dados ● Incluindo registros 1 2 3 4 5 6 7 8 9 inline int generateId(const QString &table) { QSqlQuery query; query.exec("SELECT MAX(id) FROM " + table); int id = 0; if (query.next()) id = query.value(0).toInt() + 1; return id; } Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 140 Banco de Dados ● Excluindo registros 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 } tableView->setFocus(); QModelIndex index = tableView->currentIndex(); if (!index.isValid()) return; QSqlRecord record = model->record(index.row()); QSqlTableModel cdModel; cdModel.setTable("cd"); cdModel.setFilter("artistid = " + record.value("id").toString()); cdModel.select(); if (cdModel.rowCount() == 0) { model->removeRow(tableView->currentIndex().row()); } else { QMessageBox::information(this, tr("Delete Artist"), tr("Cannot delete %1 because there are CDs associated " "with this artist in the collection.") .arg(record.value("name").toString())); Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 141 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 142 Banco de Dados ● Relacionamentos e master-detail – – – 1 2 3 4 5 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 connect(cdTableView->selectionModel(), SIGNAL(currentRowChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(currentCdChanged(const QModelIndex &))); Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 143 Lab14: Master-Detail ● Configuração da base de dados ● QSqlRelationalTableModel ● QSqlTableModel Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 144 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 145 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 146 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 147 Graphics View ● Arquitetura: – Itens pré-definidos no Qt Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 148 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 149 Graphics View ● Implementando zoom e rotação 1 2 3 4 5 6 7 8 9 10 11 class View : public QGraphicsView { Q_OBJECT ... public slots: void zoomIn() { scale(1.2, 1.2); } void zoomOut() { scale(1 / 1.2, 1 / 1.2); } void rotateLeft() { rotate(-10); } void rotateRight() { rotate(10); } ... }; Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 150 Lab15: Coordenadas ● 1 2 3 4 5 6 7 8 9 10 11 Implementar seleção de itens e operações QGraphicsScene scene; QGraphicsRectItem *rect = scene.addRect(QRectF(0, 0, 100, 100)); QGraphicsItem *item = scene.itemAt(50, 50); // item == rect QGraphicsScene scene; myPopulateScene(&scene); QGraphicsView view(&scene); view.show(); Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 151 Lab16: Novos Itens ● Implementando novos itens 1 class SimpleItem : public QGraphicsItem 2 { 3 public: 4 QRectF boundingRect() const 5 { 6 qreal penWidth = 1; 7 return QRectF(-10 - penWidth / 2, -10 - penWidth / 2, 8 20 + penWidth, 20 + penWidth); 9 } 10 11 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) 12 { 13 painter->drawRoundedRect(-10, -10, 20, 20, 5, 5); 14 } 15 }; Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 152 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 153 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 154 XML 1 2 3 <doc> <quote>Ars longa vita brevis</quote> </doc> 1 2 3 4 5 6 7 startDocument() startElement("doc") startElement("quote") characters("Ars longa vita brevis") endElement("quote") endElement("doc") endDocument() Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 155 Lab17: XML SAX ● 1 2 3 4 5 6 Exemplo de classe handler para o SAX class SaxHandler : public QXmlDefaultHandler { public: SaxHandler(QTreeWidget *tree); bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &attributes); bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName); bool characters(const QString &str); bool fatalError(const QXmlParseException &exception); 7 8 9 10 private: 11 QTreeWidget *treeWidget; 12 }; Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 156 XML ● Processando o 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 } Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 157 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 158 Lab18: XML DOM ● Lendo XML com o DOM 1 2 3 4 5 6 7 8 9 QDomDocument doc("mydocument"); QFile file("mydocument.xml"); if (!file.open(QIODevice::ReadOnly)) return; if (!doc.setContent(&file)) { file.close(); return; } file.close(); Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 159 Lab18: XML DOM ● 10 11 12 13 14 15 16 17 18 19 20 21 22 23 Lendo XML com o DOM QDomElement docElem = doc.documentElement(); QDomNode n = docElem.firstChild(); while(!n.isNull()) { QDomElement e = n.toElement(); if(!e.isNull()) { cout << qPrintable(e.tagName()) << endl; } n = n.nextSibling(); } QDomElement elem = doc.createElement("img"); elem.setAttribute("src", "myimage.png"); docElem.appendChild(elem); Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 160 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 161 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 162 Lab19: Networking ● 1 2 3 4 5 Usando o QNetworkAccessManager QNetworkAccessManager *manager = new QNetworkAccessManager(this); connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*))); manager->get(QNetworkRequest(QUrl("http://qt.nokia.com"))); Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 163 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 164 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 165 Lab20: Internacionalização ● Carregando a tradução ao iniciar a aplicaçã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 } Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 166 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 167 Multithreading ● 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Definindo e criando uma nova thread class MyThread : public QThread { Q_OBJECT protected: void run(); }; void MyThread::run() { ... } … MyThread t; t.start(); // dettach Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 168 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 169 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 170 Multithreading ● 1 2 3 4 5 6 7 8 9 10 11 12 Classe reentrante porém não thread-safe class Counter { public: Counter() { n = 0; } void increment() { ++n; } void decrement() { --n; } int value() const { return n; } private: int n; }; Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 171 Lab21: Sincronizando ● 1 2 3 4 5 6 7 8 9 10 11 12 13 Tornando a classe thread-safe class Counter { public: Counter() { n = 0; } void increment() { QMutexLocker locker(&mutex); ++n; } void decrement() { QMutexLocker locker(&mutex); --n; } int value() const { QMutexLocker locker(&mutex); return n; } private: mutable QMutex mutex; int n; }; Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 172 Lab22: QtConcurrent ● 1 2 3 4 5 6 7 8 Usando QtConcurrent // Instantiate the objects and connect to the finished signal. MyClass myObject; QFutureWatcher<int> watcher; connect(&watcher, SIGNAL(finished()), &myObject, SLOT(handleFinished())); // Start the computation. QFuture<int> future = QtConcurrent::run(...); watcher.setFuture(future); Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 173 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 174 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 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á Classe factory existentes do Qt precisa-se implementar duas para criação de novos handlers 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á Classe factory existentes do Qt precisa-se implementar duas para criação de novos handlers classes: ● Plugin Wrapper ● Plugin Handler Classe que efetivamente implementa a funcionalidade Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 177 Plugins ● Estas duas classes deverão ser filhas de classes disponibilizadas pelo Qt Wrapper QAccessibleBridgePlugin QAccessiblePlugin QIconEnginePlugin QImageIOPlugin QInputContextPlugin QPictureFormatPlugin QSqlDriverPlugin QStylePlugin QTextCodecPlugin Handler QAccessibleBridge QAccessibleInterface QIconEngine QImageIOHandler QInputContext QSqlDriver QStyle QTextCodec Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 178 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 179 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 180 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 181 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 182 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 183 FIM Desenvolvimento Cross-Platform com C++ e Qt Sandro Santos Andrade [email protected] Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 184