“What’s GNU in Virtualization”
Este é o título de um artigo publicado na Linux Magazine, que resume as principais opções para aqueles que pretendam “Virtualizar”.
Deixo-vos com esta sugestão de leitura: http://www.linux-mag.com/id/7614
Este é o título de um artigo publicado na Linux Magazine, que resume as principais opções para aqueles que pretendam “Virtualizar”.
Deixo-vos com esta sugestão de leitura: http://www.linux-mag.com/id/7614

“Em Qt, “events” são objectos, derivados da classe abstracta QEvent, que representa acontecimentos que ocorreram no seio de uma aplicação ou como resultado de actividade externa da qual é necessário tomar conhecimento. Qualquer instância da subclasse QObject pode receber e manipular “Events”, mas estes tornam-se particularmente úteis no caso dos Widgets.
“
http://doc.trolltech.com/4.5/eventsandfilters.html
As situações é que podemos sentir a necessidade de utilizar esta funcionalidade do Qt são infinitas, por isso vou apenas descrever a situação particular que me levou até os “Event Filters”.
Quando abordei a criação de um “Splashscreen” ( aqui ) ainda não me tinha apercebido que ao clicar sobre a minha “splashimage” esta desaparecia.
Tal acontece porque a classe QSplashScreen, tal como todas as outras, é derivada da classe”QObject” e, entre outros, responde ao evento de clique de rato ( QEvent::MouseButtonPress ).
Uma forma de contornar esta situação consiste em:
Exemplo 1
O “event filter” bloqueia tudo, ou seja, nem cliques de rato nem teclas podem encerrar prematuramente o “splashscreen“.
#include "mysplash.h"
mySplash::mySplash(QWidget *parent)
:QSplashScreen(parent)
{
this->installEventFilter(this);
}
bool mySplash::eventFilter(QObject *target, QEvent *event){
return true;
}
obter código aqui
Exemplo 2
Consiste numa pequena alteração que permite utilizar um “duplo clique de rato” para encerrar o “splashscreen“.
#include "mysplash.h"
mySplash::mySplash(QWidget *parent)
:QSplashScreen(parent)
{
this->installEventFilter(this);
}
bool mySplash::eventFilter(QObject *target, QEvent *event){
if(event->type() == QEvent::MouseButtonDblClick)
return false;
else
return true;
}
obter código aqui
Claro que este assunto não se esgota por aqui … mas há que continuar a investigar :)
No meu caso era.
Agora reparem na imagem ( retirada de http://www.labnol.org/internet/tools/opendsn-what-is-opendns-why-required-2/2587/ ).

Parece publicidade enganosa mas, NÃO É!
Aqueles preciosos segundos que o meu ISP, e os respectivos servidores de DNS, me estavam a fazer perder sempre que digitava um novo endereço, praticamente desapareceram.
Ainda não resolvi alguns problemas técnicos relacionados com o network-manager e a sua teimosia em alterar o conteúdo do /etc/resolv.conf mas, já agora, se tiverem a solução avisem ;)
Leitura recomendada:
http://en.wikipedia.org/wiki/Domain_Name_System
http://en.wikipedia.org/wiki/OpenDNS
http://www.labnol.org/internet/tools/opendsn-what-is-opendns-why-required-2/2587/
http://en.wikipedia.org/wiki/Resolv.conf

Este é o quarto de uma série de exemplos que preparei para demonstrar alguns aspectos relacionados com a ligação a uma base de dados MySQL, utilizando a linguagem C++/Qt.
No fundo limitei-me a criar uma versão mais simplificado do que tinha feito aqui.
Convém lembrar que este exemplo se liga ao “localhost”, à base de dados Qt, com o utilizador “qtuser” que utiliza a palavra passe “123″.
Se estas condições não forem satisfeitas, o primeiro semáforo(base de dados) nunca ficará verde.
O melhor é experimentarem que a “malta” dá as dicas que faltarem.
O código pode ser obtido aqui.
Nos pontos #1 a #6 falei sobre:
Se não se acreditarem basta carregar no golfinho para rever.
Mas de que serve tudo isto se eu não conseguir escrever /alterar/eliminar informação acerca de Jogadores e Equipas na minha base de dados?!
Por esta razão vou registar aqui uma versão reduzida do subconjunto DML ( Data Manipulation Language), cujos principais comandos são:
# SELECT
Permite obter dados a partir das tabelas.
Como neste momento as nossas tabelas ainda estão vazias o resultado é pouco esclarecedor, pelo que vamos reutilizar estes comandos mais para a frente.
mysql> SELECT * FROM Equipa; Empty set (0.00 sec) mysql> SELECT * FROM Jogador; Empty set (0.00 sec)
# INSERT
Permite inserir os dados nas tabelas.
Vamos então inserir alguns dados relativos a equipas e jogadores.
mysql> DESCRIBE Equipa; +-------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------------+-------------+------+-----+---------+-------+ | id | tinyint(3) | NO | PRI | NULL | | | nome | varchar(15) | NO | | NULL | | | nrsocios | int(7) | NO | | NULL | | | campeonatos | tinyint(2) | YES | | NULL | | +-------------+-------------+------+-----+---------+-------+ 4 rows in set (0.00 sec) mysql> INSERT INTO Equipa(id, nome, nrsocios, campeonatos) -> VALUES(1, "SCP", 1000000, 45); Query OK, 1 row affected (0.00 sec) mysql> INSERT INTO Equipa VALUES(2, "FCP", 900000, 1); Query OK, 1 row affected (0.00 sec) mysql> INSERT INTO Equipa(id, nome, nrsocios) -> VALUES(3, "SLB", 12); Query OK, 1 row affected (0.00 sec) mysql> INSERT INTO Equipa(id, nome, nrsocios) VALUES(3, "ERRO", 0); ERROR 1062 (23000): Duplicate entry '3' for key 1 mysql> SELECT * FROM Equipa; +----+------+----------+-------------+ | id | nome | nrsocios | campeonatos | +----+------+----------+-------------+ | 1 | SCP | 1000000 | 45 | | 2 | FCP | 900000 | 1 | | 3 | SLB | 12 | NULL | +----+------+----------+-------------+ 3 rows in set (0.00 sec)
# UPDATE
Permite alterar os dados previamente inseridos.
Vamos realizar algumas alterações aleatórias muito elementares.
mysql> UPDATE Equipa -> SET campeonatos = 1 -> WHERE nome = 'SCP'; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> SELECT * FROM Equipa; +----+------+----------+-------------+ | id | nome | nrsocios | campeonatos | +----+------+----------+-------------+ | 1 | SCP | 1000000 | 1 | | 2 | FCP | 900000 | 0 | | 3 | SLB | 12 | 0 | +----+------+----------+-------------+ 3 rows in set (0.00 sec)
x
# DELETE
Permite eliminar linhas/registos de uma tabela que foram previamente inseridos.
Partindo do princípio que duas das rquipas deveriam ser erradicadas do nosso campeonato, vamos realizar algumas alterações aleatórias muito elementares.
mysql> DELETE FROM Equipa -> WHERE nome <> 'SCP'; Query OK, 2 rows affected (0.00 sec) mysql> SELECT * FROM Equipa; +----+------+----------+-------------+ | id | nome | nrsocios | campeonatos | +----+------+----------+-------------+ | 1 | SCP | 1000000 | 1 | +----+------+----------+-------------+ 1 row in set (0.00 sec)
E que fique claro … NÃO SOU SPORTINGUISTA … sou futebolisticamente “ateu“.

Um splashscreen é um elemento gráfico que é exibido quando uma aplicação é iniciada.
Estes podem ser utilizados por razões puramente “estéticas” mas tornam-se particularmente úteis quando a aplicação demora algum tempo a carregar. Nestas situações é possível ir fornecendo alguma informação ao utilizador, de forma a que este saiba que a aplicação está a ser carregada.
O ponto de partida para criarmos o nosso splashscreen em Qt deverá naturalmente ser a classe que possibilita a sua criação, ou seja, QSplashScreen.
De seguida, e como um exemplo ajuda sempre, vou disponibilizar as experiências que realizei:
#1 – O básico
Surge o splashcreen enquanto a janela principal é carregada. Neste caso é tudo muito rápido pois a aplicação exemplo é minúscula.
Exemplo:
#include <QtGui/QApplication>
#include "mainwindow.h"
#include <QSplashScreen>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QPixmap pixmap("f0.png");
QSplashScreen splash;
splash.setPixmap(pixmap);
splash.show();
MainWindow w;
w.show();
splash.finish(&w);
return a.exec();
}
#2 – Garantir que o splashscreen “sobrevive” por 5 segundos, enquanto exibo uma mensagem
Exemplo:
#include <QtGui/QApplication>
#include "mainwindow.h"
#include <QSplashScreen>
#include <QTimer>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QPixmap pixmap("f0.png");
QSplashScreen splash;
splash.setPixmap(pixmap);
splash.show();
splash.showMessage(QObject::trUtf8("A preparar a janela principal ..."), Qt::AlignRight|Qt::AlignTop, Qt::black);
MainWindow w;
QTimer::singleShot(5000, &splash, SLOT(close()));
QTimer::singleShot(5000, &w, SLOT(show()));
return a.exec();
}
#3 – Tenho várias tarefas para executar, e quero ir mantendo o utilizador informado. Entretanto vou mostrando imagens diferentes.
Exemplo:
void operacao_03();
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QSplashScreen *splash = new QSplashScreen;
splash->setPixmap(QPixmap(":/splash/f2"));
splash->show();
splash->showMessage(QObject::trUtf8("A executar a operação 01 ..."), Qt::AlignRight|Qt::AlignTop, Qt::black);
operacao_01();
splash->setPixmap(QPixmap(":/splash/f1"));
splash->showMessage(QObject::trUtf8("A executar a operação 02 ..."), Qt::AlignRight|Qt::AlignBottom, Qt::black);
operacao_02();
splash->setPixmap(QPixmap(":/splash/f0"));
splash->showMessage(QObject::trUtf8("A executar a operação 03 ..."), Qt::AlignRight|Qt::AlignTop, Qt::black);
operacao_03();
MainWindow w;
w.show();
splash->finish(&w);
delete splash;
return a.exec();
}
void operacao_01(){
sleep(2);
}
void operacao_02(){
sleep(2);
}
void operacao_03(){
sleep(2);
}
Note que todas as operações foram realizadas como root.
A partir de agora deverá iniciar uma sessão com o utilizador “psi”, com o qual pode fazer “tudo o que lhe passar pela cabeça”, pois as alterações apenas irão incidir sobre a base de dados “exemplo”.
A sequência seguinte demonstra como podemos:
mysql> CREATE TABLE Equipa -> ( -> id TINYINT(3) PRIMARY KEY, -> nome VARCHAR(15) NOT NULL, -> nrsocios INT(7) NOT NULL, -> campeonatos TINYINT(2) -> ); Query OK, 0 rows affected (0.00 sec) mysql> CREATE TABLE Jogador -> ( -> nrid INT(8) PRIMARY KEY, -> nrcamisola TINYINT(2), -> nome varchar(30) NOT NULL, -> posicao VARCHAR(10) NOT NULL, -> idade TINYINT(2), -> equipa TINYINT(3) NOT NULL -> ); Query OK, 0 rows affected (0.00 sec) mysql> CREATE TABLE Lixo -> ( -> atributo1 INT(8) PRIMARY KEY, -> atributo2 TINYINT(2), -> atributo3 varchar(30) NOT NULL -> ); Query OK, 0 rows affected (0.00 sec) mysql> DESCRIBE Lixo; +-----------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------+-------------+------+-----+---------+-------+ | atributo1 | int(8) | NO | PRI | NULL | | | atributo2 | tinyint(2) | YES | | NULL | | | atributo3 | varchar(30) | NO | | NULL | | +-----------+-------------+------+-----+---------+-------+ 3 rows in set (0.00 sec) mysql> ALTER TABLE Lixo DROP COLUMN Atributo3; Query OK, 0 rows affected (0.00 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> DESCRIBE Lixo; +-----------+------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------+------------+------+-----+---------+-------+ | atributo1 | int(8) | NO | PRI | NULL | | | atributo2 | tinyint(2) | YES | | NULL | | +-----------+------------+------+-----+---------+-------+ 2 rows in set (0.00 sec) mysql> ALTER TABLE Lixo ADD COLUMN Atributo4 int(4); Query OK, 0 rows affected (0.00 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> DESCRIBE Lixo; +-----------+------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------+------------+------+-----+---------+-------+ | atributo1 | int(8) | NO | PRI | NULL | | | atributo2 | tinyint(2) | YES | | NULL | | | Atributo4 | int(4) | YES | | NULL | | +-----------+------------+------+-----+---------+-------+ 3 rows in set (0.00 sec) mysql> DROP TABLE Lixo; Query OK, 0 rows affected (0.00 sec) mysql> SHOW TABLES; +-------------------+ | Tables_in_Exemplo | +-------------------+ | Equipa | | Jogador | +-------------------+ 2 rows in set (0.00 sec)
Saber mais:
http://dev.mysql.com/doc/refman/5.0/en/create-table.html
http://dev.mysql.com/doc/refman/5.0/en/getting-information.html
http://dev.mysql.com/doc/refman/5.0/en/alter-table.html
Imagine que é um utilizador de Debian GNU/Linux e está prestes a iniciar-se no estudo das bases de dados MySQL!
Como aluno aplicado que com certeza é, vai ter todo o interesse em poder realizar todos os exercícios também na sua máquina pessoal.
Neste artigo vou tentar resumir os aspectos mais práticos no que diz respeito à instalação e utilização de uma base de dados MySQL num sistema Debian GNU/Linux.
Não vou estar com preocupações de segurança nem performance da base de dados, focando-me apenas nos aspectos que permitem obter resultados rápidos e deixando o aprofundamento dos conteúdos abordados para uma fase posterior.
Pretendo apresentar um exemplo que abrange desde a instalação do servidor até à criação de uma Base de Dados Relacional muito simples, preocupando-me apenas com a utilização dos subconjuntos da linguagem SQL de Linguagem de definição de dados (LDD ou DDL, do Inglês Data Definition Language) e de Linguagem de Controle de Dados (LCD ou DCL do inglês Data Control Language).
No caso prático em estudo vamos falar de futebol, e o modelo correspondente é o seguinte:
![]()
Os atributos associados às duas entidades são os seguintes:
Equipa (id, nome, nrsocios, campeonatos)
Jogador (numero, nome, posicao, idade, equipa)
Para evitar que este artigo fique demasiado longo vou utilizar uma estratégia semelhante à que usei aqui.
Os vários passos a seguir são apresentados aqui, na forma de uma hiperligação para um subartigo que cobre apenas essa tarefa específica, nos quais terei o cuidado de deixar alguns links para páginas com informação mais detalhada.
#1 Instalação do servidor e cliente de MySQL
#2 Iniciar uma sessão em modo interactivo
#3 Criar utilizadores
#4 Criar/Eliminar uma base de dados
#5 Definir os privilégios de acesso dos utilizadores às bases de dados
#6 Criar tabelas
#7 Utilização elementar dos comandos MySQL do subconjunto DML
Por esta altura já temos a base de dados “exemplo” e o utilizador ”psi” criados.
Para que o utilizador “psi” possa utilizar a base de dados “exemplo” é necessário atribuir-lhe privilégios de acesso.
A sequência seguinte demonstra como podemos:
mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | exemplo | | mysql | +--------------------+ 3 rows in set (0.00 sec) mysql> SHOW GRANTS FOR 'psi'; +----------------------------------------------------------------------------------------------------+ | Grants for psi@% | +----------------------------------------------------------------------------------------------------+ | GRANT USAGE ON *.* TO 'psi'@'%' IDENTIFIED BY PASSWORD '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257' | +----------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) mysql> GRANT ALL PRIVILEGES ON exemplo.* TO 'psi'@'%'; Query OK, 0 rows affected (0.00 sec) mysql> SHOW GRANTS FOR 'psi'; +----------------------------------------------------------------------------------------------------+ | Grants for psi@% | +----------------------------------------------------------------------------------------------------+ | GRANT USAGE ON *.* TO 'psi'@'%' IDENTIFIED BY PASSWORD '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257' | | GRANT ALL PRIVILEGES ON `exemplo`.* TO 'psi'@'%' | +----------------------------------------------------------------------------------------------------+ 2 rows in set (0.00 sec) mysql> REVOKE ALL ON exemplo.* FROM 'psi'@'%'; Query OK, 0 rows affected (0.00 sec) mysql> SHOW GRANTS FOR 'psi'; +----------------------------------------------------------------------------------------------------+ | Grants for psi@% | +----------------------------------------------------------------------------------------------------+ | GRANT USAGE ON *.* TO 'psi'@'%' IDENTIFIED BY PASSWORD '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257' | +----------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
Nota: Após a utilização de GRANT ou REVOKE é necessário executar o seguinte comando de forma a que as alterações tenham efeito:
mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec)
Saber mais em:
http://dev.mysql.com/doc/refman/5.1/en/grant.html
http://dev.mysql.com/doc/refman/5.0/en/revoke.html