Desenvolvimento Cross-Platform com C++ e Qt
Sandro Santos Andrade sandroandrade@kde.org
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 ● 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 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 #include
● 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:
● Arquivo de projeto automaticamente gerado neste exemplo
1 ################################################################### 2 # Automatically generated by qmake (2.01a) qua jul 21 22:43:25 2010 3 ################################################################### 4 5 TEMPLATE = app 6 TARGET = 7 DEPENDPATH += . 8 INCLUDEPATH += . 9 10 # Input 11 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
● 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:
1 bool QObject::connect(senderqobjptr, 2 SIGNAL(signalname(argtypelist)), 3 receiverqobjptr, 4 SLOT(slotname(argtypelist)) 5 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
● Um exemplo simples:
1 #include
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 53 Lab2: Signals / Slots
● Um exemplo simples:
1 void Counter::setValue(int value) 2 { 3 if (value != m_value) { 4 m_value = value; 5 emit valueChanged(value); 6 } 7 } 8 9 10 Counter a, b; 11 QObject::connect(&a, SIGNAL(valueChanged(int)), 12 &b, SLOT(setValue(int))); 13 14 a.setValue(12); // a.value() == 12, b.value() == 12 15 b.setValue(48); // 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 (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 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 QSlider (filho do (filho do QWidget) QWidget)
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 63 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 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 #include
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/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 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 #include
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 75 Lab4: Dialogs
1 #include
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 76 Lab4: Dialogs
26 QHBoxLayout *topLeftLayout = new QHBoxLayout; 27 topLeftLayout->addWidget(label); 28 topLeftLayout->addWidget( lineEdit); 39 QHBoxLayout *mainLayout = 29 new QHBoxLayout; 30 QVBoxLayout *leftLayout = 40 mainLayout->addLayout( new QVBoxLayout; leftLayout); 31 leftLayout>addLayout( 41 mainLayout->addLayout( topLeftLayout); rightLayout); 32 leftLayout->addWidget( 42 setLayout(mainLayout); caseCheckBox); 43 33 leftLayout->addWidget( 44 setWindowTitle(tr("Find")); backwardCheckBox); 45 34 46 setFixedHeight( 35 QVBoxLayout *rightLayout = sizeHint().height()); new QVBoxLayout; 47 } 36 rightLayout->addWidget( findButton); 37 rightLayout->addWidget( closeButton); 38 rightLayout->addStretch();
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 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()));
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 81 Lab5: Main Windows
● Inserindo actions em menus
1 QMenu *fileMenu = menuBar()->addMenu(tr("&File")); 2 fileMenu->addAction(newAction); 3 fileMenu->addAction(openAction); 4 fileMenu->addAction(saveAction); 5 fileMenu->addAction(saveAsAction);
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 82 Lab5: Main Windows
● Inserindo actions em toolbars
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);
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 83 Lab5: Main Windows
● Criando a barra de status
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();
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ódigo- fonte ● 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
● Implementando funcionalidade
1 #include
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 91 Lab7: Funcionalidades
● Implementando funcionalidade
1 #include
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 92 Lab7: Funcionalidades
● Implementando funcionalidade
1 #include
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 93 Lab7: Funcionalidades
● Usando modeless dialogs
1 MainWindow::MainWindow(...) 2 { 3 ... 4 findDialog = 0; 5 ... 6 } 7 8 void MainWindow::on_findAction_triggered() 9 { 10 if (!findDialog) 11 { 12 findDialog = new FindDialog(this); 13 } 14 findDialog->show(); 15 findDialog->activateWindow(); 16 }
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 94 Lab7: Funcionalidades
● Usando modal dialogs
1 void MainWindow::addCd() 2 { 3 AddCdDialog addCdDialog(this); 4 if (addCdDialog.exec()) 5 { 6 // Retorna QDialog::Accepted ou QDialog::Reject 7 ... 8 } 9 }
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 QPainter painter(this); 2 painter.setRenderHint(QPainter::Antialiasing); 3 painter.translate(width() / 2, height() / 2); 4 painter.scale(side / 200.0, side / 200.0); 5 6 painter.setPen(Qt::NoPen); 7 painter.setBrush(hourColor); 8 9 painter.save(); 10 painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0))); 11 painter.drawConvexPolygon(hourHand, 3); 12 painter.restore(); 13 14 painter.setPen(hourColor); 15 16 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 102 Lab9: Widget Relógio
1 painter.setPen(Qt::NoPen); 2 painter.setBrush(minuteColor); 3 4 painter.save(); 5 painter.rotate(6.0 * (time.minute() + time.second() / 60.0)); 6 painter.drawConvexPolygon(minuteHand, 3); 7 painter.restore(); 8 9 painter.setPen(minuteColor); 10 11 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 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
● Visualizando o sistema de arquivos
1 QFileSystemModel *model = new QFileSystemModel; 2 model->setRootPath(QDir::currentPath()); 3 4 QTreeView *tree = new QTreeView(splitter); 5 tree->setModel(model); 6 tree->setRootIndex(model->index(QDir::currentPath())); 7 8 QListView *list = new QListView(splitter); 9 list->setModel(model); 10 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 class SpinBoxDelegate : public QItemDelegate 2 { 3 Q_OBJECT 4 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 };
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 112 Lab11: Delegates
● Utilizando outros delegates
1 QWidget *SpinBoxDelegate::createEditor(QWidget *parent, 2 const QStyleOptionViewItem &/* option */, 3 const QModelIndex &/* index */) const 4 { 5 QSpinBox *editor = new QSpinBox(parent); 6 editor->setMinimum(0); 7 editor->setMaximum(100); 8 9 return editor; 10 } 11 12 void SpinBoxDelegate::setEditorData(QWidget *editor, 13 const QModelIndex &index) const 14 { 15 int value = index.model()->data(index, Qt::EditRole).toInt(); 16 QSpinBox *spinBox = static_cast
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 113 Lab11: Delegates
● Utilizando outros delegates
1 void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, 2 const QModelIndex &index) const 3 { 4 QSpinBox *spinBox = static_cast
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: ● 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 117 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 118 Generic Containers
● Iterators
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 119 Generic Containers
● Iterators Java-style
1 QList
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 120 Generic Containers
● Iterators com suporte a modificações
1 QMutableListIterator
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 121 Generic Containers
● Iterators STL-style
1 QList
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 122 Generic Containers
● Foreach
1 QLinkedList
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)
● Gravando e recuperando dados texto
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 } 7 8 9 QTextStream in("0x50 0x20"); 10 int firstNumber, secondNumber; 11 12 in >> firstNumber; // firstNumber == 80 13 in >> dec >> secondNumber; // secondNumber == 0 14 15 char ch; 16 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)
● Gravando e recuperando dados binário
1 QFile file("file.dat"); 2 file.open(QIODevice::WriteOnly); 3 QDataStream out(&file); // we will serialize the data into the file 4 out << QString("the answer is"); // serialize a string 5 out << (qint32)42; // serialize an integer 6 7 8 QFile file("file.dat"); 9 file.open(QIODevice::ReadOnly); 10 QDataStream in(&file); // read the data serialized from the file 11 QString str; 12 qint32 a; 13 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)
● 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 >>
1 QDataStream &operator<<(QDataStream &, const QXxx &); 2 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
● Executando sentenças SQL
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 }
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 135 Banco de Dados
● QSqlQuery pode ser utilizado com comandos DDL e inserts
1 QSqlQuery query; 2 3 query.exec("CREATE TABLE artist (id INTEGER PRIMARY KEY, " 4 "name VARCHAR(40) NOT NULL, country VARCHAR(40))"); 5 6 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)"); 10 11 query.exec("CREATE TABLE track (id INTEGER PRIMARY KEY, " 12 "title VARCHAR(40) NOT NULL, duration INTEGER NOT NULL, " 13 "cdid INTEGER NOT NULL)");
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 136 Banco de Dados
● Consultando com QSqlTableModel
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 }
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 137 Banco de Dados
● Ligando o model a uma view
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();
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 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 }
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 140 Banco de Dados
● Excluindo registros
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 }
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 – 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
1 connect(cdTableView->selectionModel(), 2 SIGNAL(currentRowChanged(const QModelIndex &, 3 const QModelIndex &)), 4 this, 5 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 class View : public QGraphicsView 2 { 3 Q_OBJECT 4 ... 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 };
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 150 Lab15: Coordenadas
● Implementar seleção de itens e operações
1 QGraphicsScene scene; 2 QGraphicsRectItem *rect = scene.addRect(QRectF(0, 0, 100, 100)); 3 4 QGraphicsItem *item = scene.itemAt(50, 50); 5 // item == rect 6 7 QGraphicsScene scene; 8 myPopulateScene(&scene); 9 10 QGraphicsView view(&scene); 11 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 Ars longa vita brevis
3
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 155 Lab17: XML SAX
● Exemplo de classe handler para o SAX
1 class SaxHandler : public QXmlDefaultHandler 2 { 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); 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 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();
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 159 Lab18: XML DOM
● Lendo XML com o DOM
10 QDomElement docElem = doc.documentElement(); 11 12 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 } 20 21 QDomElement elem = doc.createElement("img"); 22 elem.setAttribute("src", "myimage.png"); 23 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
● Usando o QNetworkAccessManager
1 QNetworkAccessManager *manager = new QNetworkAccessManager(this); 2 connect(manager, SIGNAL(finished(QNetworkReply*)), 3 this, SLOT(replyFinished(QNetworkReply*))); 4 5 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
● Definindo e criando uma nova thread
1 class MyThread : public QThread 2 { 3 Q_OBJECT 4 protected: 5 void run(); 6 }; 7 8 void MyThread::run() 9 { 10 ... 11 } 12 13 … 14 MyThread t; 15 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
● Classe reentrante porém não thread-safe
1 class Counter 2 { 3 public: 4 Counter() { n = 0; } 5 6 void increment() { ++n; } 7 void decrement() { --n; } 8 int value() const { return n; } 9 10 private: 11 int n; 12 };
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 171 Lab21: Sincronizando
● Tornando a classe thread-safe
1 class Counter 2 { 3 public: 4 Counter() { n = 0; } 5 6 void increment() { QMutexLocker locker(&mutex); ++n; } 7 void decrement() { QMutexLocker locker(&mutex); --n; } 8 int value() const { QMutexLocker locker(&mutex); return n; } 9 10 private: 11 mutable QMutex mutex; 12 int n; 13 };
Desenvolvimento Cross-Platform com C++ e Qt - Sandro Santos Andrade - Live Blue 172 Lab22: QtConcurrent
● Usando QtConcurrent
1 // Instantiate the objects and connect to the finished signal. 2 MyClass myObject; 3 QFutureWatcher
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 implementarpara criação de duas classes: novos handlers
● 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 implementarpara criação de duas classes: novos handlers
● Plugin Wrapper Classe que efetivamente ● implementa a Plugin Handler 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 Handler
QAccessibleBridgePlugin QAccessibleBridge QAccessiblePlugin QAccessibleInterface QIconEnginePlugin QIconEngine QImageIOPlugin QImageIOHandler QInputContextPlugin QInputContext QPictureFormatPlugin - QSqlDriverPlugin QSqlDriver QStylePlugin QStyle QTextCodecPlugin 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