Como criar um botão personalizado com GtkEventBox

Explicação

Existem varias formas de estilizar uma aplicação, porem algumas aplicações precisam de muito mais, como por exemplo um jogo, que precisa de menus e outras coisas. De qualquer forma, criar um botão personalizado com imagens pode ajudar muito nessa tarefa. Uma maneira fácil de fazer isso, é utilizar um GtkEventBox e verificar vários sinais e ir tratando qual imagem mostrar. Sim, ta um bom trabalho faze-lo, pois existe um sinal para a troca de imagem, que é o expose_event. Com ele, seu callback é chamado toda vez que widget aparecer ou for "pintado" novamente, assim conseguimos ter um efeito de quando o mouse entra e sai do nosso botão.

Imagem

Captura_de_tela-botao.class.php

Solução

Cria um GtkEventBox();
Conectar o GtkEventBox() a todos os sinais;
Verificar o Mouse Over, Mouse Out e o Expose;
Tratar qual imagem mostrar em cada sinal.

Exemplo

widgets['fixTeste'] = new GtkFixed();
			
			// Cria a janela
			$this->widgets['frmTeste'] = new GtkWindow();
			$this->widgets['frmTeste']->set_size_request(200, 200);
			
			// Cria o eventbox
			$this->widgets['evtTeste'] = new GtkEventBox();
			$this->widgets['evtTeste']->set_size_request(59, 103);
			$this->widgets['fixTeste']->put($this->widgets['evtTeste'], 8, 8);
			
			// Conecta o eventbox ao evento de "pintura"
			$this->widgets['evtTeste']->connect(
				"expose_event", 
				array($this, "evtTeste_onPrint")
			);
			
			// Conecta o eventbox aos eventos
			$this->widgets['evtTeste']->connect(
				"event", 
				array($this, "evtTeste_onEvent")
			);
			
			// Mostra a janela
			$this->widgets['frmTeste']->add($this->widgets['fixTeste']);
			$this->widgets['frmTeste']->show_all();
			
			// Conecta o destroy
			$this->widgets['frmTeste']->connect_simple(
				"destroy", 
				array("Gtk", "main_quit")
			);
		}
		
		// Método que trata os eventos do evtTeste
		public function evtTeste_onEvent($widget, $event)
		{
			switch($event->type)
			{
				// On Mouse Over
				case 10:
					// Muda a imagem
					$this->evtTesteImage = "btn02.png";
					$this->widgets['evtTeste']->queue_draw();
					
					// Muda o cursor
					$cursor = new GdkCursor(Gdk::HAND2);
					$widget->window->set_cursor($cursor);
					break;
					
				// On Mouse Out
				case 11:
					// Muda a imagem
					$this->evtTesteImage = "btn01.png";
					$this->widgets['evtTeste']->queue_draw();
					break;
			}
		}
		
		// Método que pinta o evtTeste
		public function evtTeste_onPrint($widget, $event)
		{
			$pixbuf = GdkPixbuf::new_from_file($this->evtTesteImage);
			
			$w = $pixbuf->get_width();
			$h = $pixbuf->get_height();
			$x = $widget->allocation->width - $w;
			$y = 0;
			$widget->window->draw_pixbuf(
				$widget->style->bg_gc[Gtk::STATE_NORMAL], 
				$pixbuf, 
				0, 
				0, 
				$x, 
				$y
			);

			return TRUE;
		}
	}

	// Inicia a aplicação
	$teste = new Teste();
	gtk::main();

Referências

http://gtk.php.net/manual/en/gtk.gtkwidget.php