minicurso qt - usp - liveblue.files.wordpress.com · minicurso qt - usp objetivos: he has the...

Post on 30-Jul-2018

238 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Minicurso Qt - USP( Ou a construção do Caos)

Minicurso Qt - USP

Minicurso Qt - USPPorque Qt?

- C++ / Orientação a Objetos- Moc- Sinais / Slots- Genealogia- Widgets- Threads- Multimedia- XML- Banco de Dados- Animações- Multiplataforma- Leve- i18n, l10n. ( seja lá o que isso quer dizer )- Programação Concorrente- Sockets

Minicurso Qt - USP

Pré Requisitos:

Orientação a Objetos( Seja Java, Python, Ruby ou whattahell )

Vontade de aprender

Desejavel:

Conhecimentos em C++

Minicurso Qt - USPObjetivos:

He Has the technology, He can make you Better, Faster, Stronger.

- Introduzir o Qt de forma Prática

- Iniciar uma vivência em Grupo

- Discutir Relações de Projeto

- Distribuir Balinhas de Banana

Minicurso Qt - USPMétodologia:

- Aula Prática com intervenções artisticas.- Meia hora de Aula para Meia hora de

Implementação.- Xp Programming - 2 alunos por computador

Referências:- Qt Quaterly- Qt Documentation- api.kde.org- labs.trolltech.com- Qt Center

Minicurso Qt - USP

C++ ( ou o testamento da ira)

Minicurso Qt - USP

C++:Baixo nivelAlto nivelFlexivelCódigo GenéricoOrientada a ObjetosEstruturadaconst char *const a()

Minicurso Qt - USPconst não é Constante.

const é Muita coisa:

const int a = 10;

const char *const b = "waha";

int Classe::blah() const;

const int *const Classe::bleh() const;

Minicurso Qt - USP

const é 'somente leitura'

const int a = 10;

Valendo 1 bala.

Minicurso Qt - USP

const é não - modificavel.int const* a;

const é somente-leitura-não-modificavelconst char * const a = "nãomudo."

const método não pode alterar o objeto.void Classe::metodo() const;

Minicurso Qt - USP

Valores · Ponteiros · Referencias

int a; ← valorint *b; ← ponteiroint &c; ← referencia

Diferenças? ( Balinhas )

Minicurso Qt - USP

class A {public:

A(); ← ConstrutorA(const A& a); ← Balinha~A(); ← Destrutor

}; ← Sim, ponto - e - virgula.

Minicurso Qt - USP

class A{virtual void blah() = 0;virtual void bleh();bool geh() const;

};

Minicurso Qt - USP

C++ NÃO é Compativel com C.

Válido em C, Inválido em C++

void a(void){int new = 2;

}

exemplos no quadro, Valendo Balinha.

C++ NÃO é OO

Chocante, não?

- Linguagem Genérica- Caracteristicas OO- Caracteristicas Estruturada- Caracteristicas Funcionais- Caracteristicas OE

#include <cstring>#include <cstdio>

int main(){ char *letras =(char*) "salvesalvesimpatia"; if (strlen(letras) < -1){ printf("Pois é..."); } return 0;}

Brincadeira do C - Do - Mal

Brincadeira do C - Do - Mal

size_t strlen( const char* c);typedef unsigned int size_t;

-1 não é unsigned.size_t é.

Qual o problema?

Minicurso Qt - USP

Pequena História do Qt

4.0 - 2005 - Tulip- Arthur- ItemView- Scribe- MainWindow

4.1 - 2005- svg- pdf

Minicurso Qt - USP

4.2 - 2006

- Windows Vista- CSS- QGraphicsView

4.3 - 2007

- Melhorias no Vista- Melhorias no SVG- Pdf Print- QScript

Minicurso Qt - USP

4.4 - 2008

- Phonon- XML Aperfeiçoado- QtConcurrent- WebKit- IPC para Threads

4.5 - 2009

- Qt Creator- QGraphicsView++- WebKit++- OpenDocument

Minicurso Qt - USP

4.6 - 2009

- Animações- Gestures- Multi-Touch- Performance++

4.7 - 2010*

- QML- Kinetic

Minicurso Qt - USP

Minicurso Qt - USP

Minicurso Qt - USP

Minicurso Qt - USP

Minicurso Qt - USP

Minicurso Qt - USP

Minicurso Qt - USP

Visão Geral - Qt

Sinais - Slots - Containers - Meta - Objetos - CSS - Scripting - Multimídia - SVG - Bindings Para outras Linguagens - Qwt - Qanava - Wt ( ... )

História

Primeira versão em 1995, por Haavard Nord e Eirik Chambe-Eng;

Iniciou em 1991 e em 1993 já existia um núcleo que suportava widgets;

A letra 'Q' foi escolhida porque era bonita no editor do Haavard;

O “t” vem da palavra toolkit; Em 1994 foi fundada a Trolltech, antes Troll Tech

e ainda antes Quasar Technologies;

Em 1996 foi lançado o Qt 1.1 e a Trolltech tinha 8 clientes;

Também em 1996 o projeto KDE foi fundado por Matthias Ettrich;

O 'K' (do KDE) era simplesmente a letra que vinha antes do 'L';

Em 1997 o Qt passa a ser utilizado no KDE e a versão 1.3 é lançada;

Em 1999, o Qt 2 passa a ser licenciado pela QPL;

História

Em 2000 é lançado o Qtopia (Qt para ambientes embarcados);

Neste mesmo, o Qt passa a ser licenciado pela GPL;

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.

História

Hello, Qt

#include <QApplication>#include <QLabel>

int main(int argc, char *argv[]){QApplication app(argc, argv);QLabel l("Oi Mundo");l.show();return app.exec();

}

Para executar:

qmake --projectqmakemake

QMake?

Ferramenta de Gerenciamento da Compilação

Cria e Altera arquivos de Projetos, e manipula Makefiles.

Arquivos .pro devem ser editados manualmente as vezes.

Arquivo de Projeto?

######################################################### Automatically generated by qmake (2.01a) Sat Mar 6 16:50:32 2010########################################################

TEMPLATE = appTARGET = DEPENDPATH += .INCLUDEPATH += .

# InputSOURCES += main.cpp

Sobre o Hello Qt

QApplication:

Controla a camada de eventos, sinais e conexões do Qt.

QLabel:

Um Widget que exibe um texto na tela.

Sinais / Slots : Comunicação entre objetosProperties : Atributos DinâmicosMeta-Objects: Informação de Tipo Eventos e FiltrosTraduções Contextuais.

Modelo de Objetos

Sinais e Slots

- Forma padrão de Comunicação- Só são processados a partir do exec()- Um sinal é uma mensagem enviada.- Um slot é o que fazer quando receber a mensagem.

Conectando Sinais e Slots

#include <QMainWindow>#include <QLabel>#include <QSpinBox>

class Janela : public QMainWindow{Q_OBJECTpublic:

Janela();private:

QLabel m_texto;QSpinBox m_spin;

};

Conectando Sinais e Slots

Janela::Janela() : QMainWindow(){m_texto = new QLabel("");m_spin = new QSpinBox();

connect(m_spin, SIGNAL(valueChanged(QString)),m_texto, SLOT(setText(QString)));

QWidget *centralWidget = new QWidget(this); QHBoxLayout *l = new QHBoxLayout(); l->addWidget(m_texto); l->addWidget(m_spin); centralWidget->setLayout(l); setCentralWidget(centralWidget);}

Sinais

Podem se conectar a vários SlotsPodem se conectar a vários Sinais

connect( m_c1, SIGNAL(triggered()), m_c2connect( m_c1, SIGNAL(triggered()), m_c3connect( m_c1, SIGNAL(triggered()), m_c4

Qual o problema disso? ( Balinha )

Sinais - Sinais

m_b1 = new QPushButton(this);m_b2 = new QPushButton(this);

connect(m_b1, SIGNAL(clicked()), m_b2, SIGNAL(clicked()));

connect(m_b1, SIGNAL(hovered()), m_b2, SIGNAL(hovered()));

connect(m_b1, SIGNAL(activated()), m_b2, SIGNAL(activated()));

Slots - Slots ?

connect(m_b1, SLOT(clicked()), m_b2, SLOT(clicked()));

connect(m_b1, SLOT(hovered()), m_b2, SLOT(hovered()));

connect(m_b1, SLOT(activated()), m_b2, SLOT(activated()));

connect(m_b1, SLOT(clicked()), m_b2, SLOT(clicked()));

connect(m_b1, SLOT(hovered()), m_b2, SLOT(hovered()));

connect(m_b1, SLOT(activated()), m_b2, SLOT(activated()));

Slots - Slots ?

Declarando SIGNALS

class MeuQObject : public QObject{Q_OBJECTpublic:

MeuQObject();signals: ← HÁ!

void meuSinalFofo();void pos3d(int x, int y, int x);void pos2d(int x, int y);

};

Declarando Sinais

NÃO! NÃO! NÃO! NÃO!

void Classe::meuSinalFofo(){...

}void Classe::pos2d(int x, int y){

...}

Como isso funciona?

Usando seus Sinais

void Classe::mouseClick2d(mouse s){QPointF f = s.pos();if ( f.x() < 0 || f.x > screen().size()){

return;}

emit pos2d(f.x(), f.y());}

Criando seus Slots

Class MainWindow::QMainWindow{Q_OBJECTpublic:

MainWindow();

private slots:void setPonto2d(int x, int y);void setX(int x);void setY(int y);

}

Criando seus Slots

void MainWindow::setPonto2d(int x, int y){setX(x);setY(y);

}

void MainWindow::setX(int x){ m_x = x; }

void MainWindow::setY(int y){ m_y = y; }

Seus Sinais + Seus Slots

MainWindow::MainWindow(){MeuQObject *o = new MeuQObject();connect(o, SIGNAL(pos2d(int,int))

this, SLOT(setPos(int,int)));connect(o, SIGNAL(pos2d(int,int)),

this, SLOT(setX(int)));connect(o, SIGNAL(pos2d(int,int)),

this, SLOT(setY(int))); ← BALINHA!}

Calculadora + Designer

Designer

Caixa de Ferramentas

Botões, Caixas,Textos, Layouts,Controles, Radios,etc.

Editor de Propriedades do Objeto

Designer

Voltando a Calculadora

Voltando a Calculadora

Layouts

Organização de Widgets na Tela

- Verticais- Horizontais- Formulários em Colunas- Grade- Expansiveis via Sobrecarga

Layouts

o Calc.ui amava o ui_calc.hque amava o calc.hque amava o calc.cppQue não amava ninguem.e o QWidget segurava vela.

Ciranda

QChar sinal; bool esperandoPorSinal; void calcular(QChar s);

private slots: void numPressed(); void enterPressed(); void clearPressed(); void signalPressed();};

class Calc : public QWidget,public Ui::calc{

Q_OBJECT public: Calc(); private: QString numero; QString memoria;

Calc.h

foreach(QPushButton *b, botoes){ connect(b, SIGNAL(clicked()),

this, SLOT(numPressed())); }

connect(benter, SIGNAL(clicked()),

this, SLOT(enterPressed())); connect(bclear, SIGNAL(clicked()),

this, SLOT(clearPressed()));}

Calc::Calc()

Calc::Calc(){ setupUi(this); numero = "0"; memoria = "0"; lcd->display(numero); QList<QPushButton*> botoes; botoes << b1 << b2 << b3 << b4 << b5 << b6 << b7 << b8 << b9 << b0;

void Calc::clearPressed(){ memoria = '0'; numero = '0'; lcd->display(numero);}

void Calc::signalPressed(){ numero = QString(); QPushButton *b = sender(); sinal = b->text()[0];}

Calc::*Pressed()

void Calc::numPressed(){ QPushButton *b = sender(); numero += b->text(); lcd->display(numero);}

void Calc::enterPressed(){ calcular(sinal); numero = QString();}

Calc::calcular()

void Calc::calcular(QChar s){ qreal n1 = memoria.toDouble(); qreal n2 = numero.toDouble();

switch( s.toAscii() ){ case '+' : n1 += n2; break; case '-' : n1 -= n2; break; case '*' : n1 *= n2; break; case '/' : n1 /= n2; break; } memoria = QString("%1").arg(n1); lcd->display(memoria); }

Sinais - Slots

QLayouts - De novo =)

#include <QWidget>#include <QApplication>#include <QList>#include <QPushButton>#include <QVBoxLayout>#include <QHBoxLayout>

int main(int argc, char *argv[]){QApplication app(argc, argv);

QWidget *janela = new QWidget();QVBoxLayout *layout1 = new QVBoxLayout();QVBoxLayout *layout2 = new QVBoxLayout();QHBoxLayout *layoutCentral = new QHBoxLayout();

for(int i = 0; i < 10; i++){QPushButton *b = new QPushButton(janela);b->setText(QString("Botao n%1").arg(i));if (i%2){

layout1->addWidget(b);}else{

layout2->addWidget(b);}

}layoutCentral->addLayout(layout1);layoutCentral->addLayout(layout2);janela->setLayout(layoutCentral);janela->show();return app.exec();

}

Parentesco

Widgets tem Pais.O Pai de Todos tem parent() == 0

Widgets mortos, Matam os filhos junto.

Propagam Eventos pela arvore de parentesco.

Parentesco

Manipulador de Imagens

Manipulador de Imagens

class JPrincipal : public QWidgetprivates: void adicao() void subtracao() void negativa() void threshould() void tonsDeCinza() void historigrama()

Class JPrincipal : Membros

private: QLabel *m_image; QSlider *m_red; QSlider *m_green; QSlider *m_blue; QComboBox *m_opcoes;

QSlider

Seleção de Valores em uma faixa

sinais:valueChanged()sliderPressed()sliderMoved()sliderReleased()

QLabel

Guarda TextoGuarda ImagemGuarda Animação

Ultra - Versátil =)

QComboBox

Valores em Drop - DownAceita modelsAceita listasAceita adição - na - mão.

Construtor

m_red = new QSlider(Qt::Horizontal, this);

m_red ->setRange(0, 255);

m_image = new QLabel("Imagem Aqui", this);

m_opcoes = new QComboBox(this);

m_opcoes->addItem(tr("Adicao"));

QHBoxLayout *h = new QHBoxLayout();

h->addWidget(m_red);

Construtor

QVBoxLayout *v = new QVBoxLayout(this);v->addWidget(m_image);v->addWidget(m_opcoes);v->addLayout(h);

connect(m_opcoes, SIGNAL(currentIndexChanged(QString)), this, SLOT(executeAlgorithm(QString)));

connect(m_red, SIGNAL(sliderReleased()), this, SLOT(intCanais()));

executeAlgorithm

void JPrincipal::executeAlgorithm(const QString &s){ /* */if ( s == "Adicao") adicao (); else if ( s == "Subtracao") subtracao (); else if ( s == "Negativa") negativa (); else if ( s == "Threshould") threshould (); else if ( s == "TonsDeCinza") tonsDeCinza (); else if ( s == "Historigrama") historigrama ();}

void JPrincipal::tonsDeCinza(){ QPixmap p("imagem.jpg"); QImage i = p.toImage().scaled(QSize(800,600)); for( int row = 0; row < i.width(); ++row){ for( int column = 0; column < i.height(); ++ column){ QColor pixel = i.pixel(row, column); uint total = (pixel.red() *0.299f) + (pixel.green() * 0.587f) + (pixel.blue() * 0.114f); QColor c(total, total, total); i.setPixel(row, column, c.rgb() ); } }

p = p.fromImage(i); m_image->setPixmap(p); }

Tons de Cinza

Limiar

void JPrincipal::threshould(){ QPixmap p("/home/tomaz/Multimedia/Fotos/Bella/bella.jpg"); QImage i = p.toImage().scaled(QSize(800,600)); for( int row = 0; row < i.width(); ++row){ for( int column = 0; column < i.height(); ++ column){ QColor c = i.pixel(row, column); qreal limiar = c.blueF() + c.redF() + c.greenF();; i.setPixel(row, column, (limiar > 2.5f) ? 0xFFFFFF : 0x0); } } p = p.fromImage(i); m_image->setPixmap(p);}

Negativa

void JPrincipal::negativa(){ QPixmap p("foto.jpg"); QImage i = p.toImage().scaled(QSize(800,600)); for( int row = 0; row < i.width(); ++row){ for( int column = 0; column < i.height(); ++ column){ QColor c = i.pixel(row, column); c = QColor(255-c.red(), 255-c.green(), 255-c.blue()); i.setPixel(row, column, c.rgb()); } } p = p.fromImage(i); m_image->setPixmap(p);}

Resultado

QPixmap

Otimizada para representar ImagensPode ser usada em QLabel, QPushButtonCompartilhamento Implicito de dadosCarregado de um QImage

QImage

Manipulação de BitsPode ser usado com painterexecução supimpa em acesso de bitsthread safe =D

QColor

Representa uma cor

Widgets que Não Existem?

void JPrincipal::historigrama(){ QPixmap p("fotos.jpg");

THistorigram *t = new THistorigram(p);

t->resize(255,255); t->show();

p = p.fromImage(i); m_image->setPixmap(p);}

THistorigram::THistorigram(QPixmap p, QWidget *parent) : QWidget(parent){ m_r.resize(255); m_g.resize(255); m_b.resize(255); QImage i = p.toImage().scaled(QSize(800,600)); for( int row = 0; row < i.width(); ++row){

for( int column = 0; column < i.height(); ++ column){ QColor c = i.pixel(row, column); if (c.red() != 0){ m_r[c.red()-1 ] += 1; } if (c.green() != 0){ m_g[c.green()-1] += 1; } if (c.blue() != 0){ m_b[c.blue()-1 ] += 1; } } }

setBackgroundRole(QPalette::Base); setAutoFillBackground(true);}

thistorigram.h

QSize THistorigram::minimumSizeHint() const{ return QSize(255, 255); }QSize THistorigram::sizeHint() const{ return QSize(255, 255); }

void THistorigram::paintEvent ( QPaintEvent * /*event*/ ){ QPainter p(this); QLine line;

int max = 0; p.setPen(Qt::red); drawLines(p, max, m_r); p.setPen(Qt::green);drawLines(p, max, m_g); p.setPen(Qt::blue); drawLines(p, max, m_b); if (height() != max){ resize(255, max); } }

Historigrama =D

drawLines

void THistorigram::drawLines(QPainter &p, int& max, QVector<int>& vetor){ for(int i = 0; i < 250; ++i){ int p1 = vetor[i]/10; int p2 = vetor[i+1]/10; if (p1 > max) max = p1; if (p2 > max) max = p2; p.drawLine(i, p1, i+1, p2); }}

ResultadoQPainter

pintura low levelQPen

cor, estilo e espessura da linhaQBrush

balinha.

sizeHintminimumSizeHint

Pai de Todos - QMainWindow

QMenuBar- Menus de Opções

QToolBar- Icones de Opções

QDockWidget- Caixas flutuantes

QStatusBar- Status do aplicativo

QWidget- Centro do programa

QMenuBar

Relacionados:QMenuQAction

Container de MenusCada Menu Guarda MenusCada Menu Guarda QActionsCada Menu Guarda Separadores

QToolBar

Relacionados:QAction

Cada QToolBar contem n QActionsCada QToolBar é MóvelCada QToolBar pode ser EscondidaCada QToolBar pode escolher onde ficar

QActions?

Sim.

Consistência entre Menu e ToolbarQuando ativado, triggered();Imagem, Tooltip, Texto, Formato, etc.

Diga não a Duplicação de código com QAction.

Escrevendo Feliz

Escrevendo Feliz

#include <QApplication>#include "dfeliz.h"int main(int argc, char *argv[]){

QApplication app(argc, argv);DFeliz janela;janela.show();return app.exec()

}

Escrevendo Feliz - QActions

void DFeliz::setupActions(){ m_save = new QAction("Save", this); m_save->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_S)); connect(m_save, SIGNAL(triggered()), this, SLOT(save_file())); m_new = new QAction("New", this); m_new->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_N)); connect(m_new, SIGNAL(triggered()), this, SLOT(new_file()));}

Escrevendo Feliz - Menus

void DFeliz::setupUi(){ QMenuBar *m = menuBar(); QMenu *fileMenu = m->addMenu(tr("&File")); fileMenu->addAction(m_new); fileMenu->addAction(m_save);

QToolBar *toolBar = addToolBar(tr("Principal")); toolBar->addAction(m_new); toolBar->addAction(m_save);}

Salvando o Arquivo

void DFeliz::save_file(){ m_file = QFileDialog::getSaveFileName (); if ( m_file.isEmpty() ) return; QFile file(m_file); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) return;

QTextStream out(&file); out << m_textEdit->toPlainText(); file.close();}

class DFeliz : public QMainWindow {Q_OBJECTpublic: DFeliz();private: QAction *m_new; QAction *m_save; QAction *m_cut; QAction *m_paste; QTextEdit *m_textEdit; QString m_file;private slots: void new_file(); void save_file();};

Classinteira ;)

Implementem o resto

cut, copy, paste, e abrir arquivo.

vamos. Enquanto isso eu ando de um lado pra o outro e ignorando pedidos de ajuda por uns 5 minutos.

QThread

Threads MultiplataformaPThreads no LinuxWindows::Threads no Windows

Gerenciamento de Sinais / Slots

QObjects? NahQWidgets? Nah

Exemplo de Threads

class MainWindow : public QMainWindow{Q_OBJECT

public: MainWindow(QWidget *parent = 0); private: ThreadReader* grupo1; ThreadCreator* grupo2; QStringList bagOfTasks; QMutex read; QMutex write;};

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ QHBoxLayout *l = new QHBoxLayout(); QTextEdit *e; for (int i = 0; i < 5; i++){ e = new QTextEdit(this); l->addWidget(e); grupo1 = new ThreadReader(bagOfTasks, read); grupo2 = new ThreadCreator(bagOfTasks, i, write); connect(grupo1, SIGNAL(sendMessage(const QString&)),

e, SLOT(append(const QString&))); grupo2->start(); grupo1->start(); }

QWidget *centralWidget = new QWidget(this); setCentralWidget(centralWidget); centralWidget->setLayout(l); }

MainWindow

void ThreadCreator::update(){ if (_bag.size() >= 20) return; _mutex.lock(); QString conteudo; for(int i = 0; i < 4; i++) conteudo += QChar(rand()%65 + 32); _bag << QString("Thread %1 \t %2 \t %3 ") .arg(_number) .arg(conteudo) .arg(_total++); _mutex.unlock(); }

Thread::Criador

void ThreadCreator::run(){ QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout()),

this, SLOT(update())); timer->start(250); exec();}

Thread::Criador

void ThreadReader::update(){ if (_bag.empty()) return; _mutex.lock(); emit sendMessage(_bag.takeFirst()); _mutex.unlock();}

Thread::Leitor

top related