wxPython - Guia rápido

wxPython é um wrapper Python para wxWidgets(que é escrito em C ++), um popular kit de ferramentas de interface de usuário para várias plataformas. Desenvolvido por Robin Dunn junto com Harri Pasanen, wxPython é implementado como um módulo de extensão Python.

Assim como wxWidgets, wxPython também é um software livre. Ele pode ser baixado do site oficialhttp://wxpython.org. Binários e código-fonte para várias plataformas de sistema operacional estão disponíveis para download neste site.

Os módulos principais na API wxPython incluem um módulo principal. Isso consiste dewxObjectclasse, que é a base para todas as classes da API. O módulo de controle contém todos os widgets usados ​​no desenvolvimento de aplicativos GUI. Por exemplo, wx.Button, wx.StaticText (análogo a um rótulo), wx.TextCtrl (controle de texto editável), etc.

wxPython API possui módulo GDI (Graphics Device Interface). É um conjunto de classes usadas para desenhar em widgets. Classes como fonte, cor, pincel, etc. fazem parte disso. Todas as classes da janela do contêiner são definidas no módulo do Windows.

O site oficial do wxPython também hospeda o Projeto Phoenix - uma nova implementação do wxPython para Python 3. *. Ele se concentra em melhorar a velocidade, capacidade de manutenção e extensibilidade. O projeto teve início em 2012 e ainda está em fase beta.

janelas

Binários pré-construídos para o sistema operacional Windows (32 e 64 bits) estão disponíveis em http://www.wxpython.org/download.phppágina. As versões mais recentes dos instaladores disponíveis são - wxPython3.0-win32-3.0.2.0-py27.exe para Python 2.7 de 32 bits wxPython3.0-win64-3.0.2.0-py27.exe para Python 2.7 de 64 bits

wxPython demo, samples e documentação wxWidgets também estão disponíveis para download na mesma página.

wxPython3.0-win32-docs-demos.exe

Linux

Os binários wxPython para muitas distros Linux podem ser encontrados em seus respectivos repositórios. Os gerenciadores de pacotes correspondentes deverão ser usados ​​para baixar e instalar. Por exemplo, no Debian Linux, o comando a seguir deve ser capaz de instalar wxPython.

sudo apt-get install python-wxgtk3.0

Mac OS

Binários pré-construídos para MacOS na forma de imagens de disco estão disponíveis na página de download do site oficial.

Um aplicativo GUI simples que exibe a mensagem Hello World é construído usando as seguintes etapas -

  • Módulo de importação wx.

  • Defina um objeto da classe Application.

  • Crie uma janela de nível superior como objeto da classe wx.Frame. Os parâmetros de legenda e tamanho são fornecidos no construtor.

  • Embora outros controles possam ser adicionados ao objeto Frame, seu layout não pode ser gerenciado. Portanto, coloque um objeto Painel no Quadro.

  • Adicione um objeto StaticText para exibir 'Hello World' em uma posição desejada dentro da janela.

  • Ative a janela do quadro pelo método show ().

  • Insira o loop de evento principal do objeto Aplicativo.

import wx 
 
app = wx.App() 
window = wx.Frame(None, title = "wxPython Frame", size = (300,200)) 
panel = wx.Panel(window) 
label = wx.StaticText(panel, label = "Hello World", pos = (100,50)) 
window.Show(True) 
app.MainLoop()

O código acima produz a seguinte saída -

wxFrame objecté a janela de nível superior mais comumente usada. É derivado dewxWindow class. Um quadro é uma janela cujo tamanho e posição podem ser alterados pelo usuário. Possui uma barra de título e botões de controle. Se necessário, outros componentes como barra de menu, barra de ferramentas e barra de status podem ser ativados. Uma janela wxFrame pode conter qualquer quadro que não seja um diálogo ou outro quadro.

Criar uma GUI com boa aparência por meio de codificação manual pode ser entediante. Uma ferramenta de designer de GUI visual é sempre útil. Muitos IDEs de desenvolvimento de GUI direcionados a wxPython estão disponíveis. A seguir estão alguns deles -

  • wxFormBuilder
  • wxDesigner
  • wxGlade
  • BoaConstructor
  • gui2py

wxFormBuilderé um construtor de GUI WYSIWYG de plataforma cruzada de software livre que pode traduzir o design da GUI wxWidget em formato C ++, Python, PHP ou XML. Uma breve introdução ao uso de wxFormBuilder é fornecida aqui.

Em primeiro lugar, a versão mais recente do wxFormBuilder precisa ser baixada e instalada em http://sourceforge.net/projects/wxformbuilder/. Ao abrir o aplicativo, um novo projeto com uma área cinza em branco no centro aparece.

Dê um nome adequado ao projeto e escolha Python como linguagem de geração de código. Isso é feito na janela de propriedades do objeto, conforme mostrado na imagem a seguir -

Em seguida, na guia 'Formulários' da paleta de componentes, escolha Quadro.

Adicione um wxBoxSizer vertical na guia 'Layouts'.

Adicione os controles necessários na caixa com legendas adequadas. Aqui, um StaticText (rótulo), dois objetos TextCtrl (caixas de texto) e um objeto wxButton são adicionados. O quadro se parece com a seguinte imagem -

Ative Expandir e Esticar nesses três controles. Nas propriedades do objeto para o objeto wxButton, atribua uma função findquare () ao evento OnButtonClick.

Salve o projeto e pressione F8 para gerar o código Python para a GUI desenvolvida. Deixe o arquivo gerado ser nomeado como Demo.py

No script Python executável, importe demo.py e defina a função FindSquare (). Declare o objeto Aplicativo e inicie um loop de evento principal. A seguir está o código executável -

import wx 
  
#import the newly created GUI file 
import demo  
class CalcFrame(demo.MyFrame1): 
   def __init__(self,parent): 
      demo.MyFrame1.__init__(self,parent)  
		
   def FindSquare(self,event): 
      num = int(self.m_textCtrl1.GetValue()) 
      self.m_textCtrl2.SetValue (str(num*num)) 
        
app = wx.App(False) 
frame = CalcFrame(None) 
frame.Show(True) 
#start the applications 
app.MainLoop()

O código acima produz a seguinte saída -

WxWidgets original (escrito em C ++) é uma enorme biblioteca de classes. As classes GUI desta biblioteca são transportadas para Python com o módulo wxPython, que tenta espelhar a biblioteca wxWidgets original o mais próximo possível. Portanto, a classe wx.Frame em wxPython age da mesma forma que a classe wxFrame em sua versão C ++.

wxObject é a base para a maioria das classes. Um objeto de wxApp (wx.App em wxPython) representa o próprio aplicativo. Depois de gerar a GUI, o aplicativo entra em um loop de eventos pelo método MainLoop (). Os diagramas a seguir descrevem a hierarquia de classes das classes GUI mais comumente usadas incluídas no wxPython.

SN Classes e descrição
1 wx.Frame

wx.Frame Class possui um construtor padrão sem argumentos.

2 wx.Panel

A classe wx.Panel geralmente é colocada dentro de um objeto wxFrame. Esta classe também é herdada da classe wxWindow.

3 wx.StaticText

O objeto de classe wx.StaticText apresenta um controle que contém esse texto somente leitura. Pode ser denominado como um controle passivo, pois não produz nenhum evento.

4 TextCtrl

Em wxPython, um objeto da classe wx.TextCtrl serve para esse propósito. É um controle no qual o texto pode ser exibido e editado.

5 RadioButton e RadioBox

Cada botão, um objeto da classe wx.RadioButton, carrega um rótulo de texto próximo a um botão redondo. A API wxPython também consiste na classe wx.RadioBox. Seu objeto oferece uma borda e um rótulo ao grupo.

6 wx.CheckBox

Uma caixa de seleção exibe uma pequena caixa retangular rotulada. Quando clicado, uma marca de seleção aparece dentro do retângulo para indicar que uma escolha foi feita.

7 ComboBox e classe de escolha

Um objeto wx.ComboBox apresenta uma lista de itens para seleção. Ele pode ser configurado para ser uma lista suspensa ou com exibição permanente. A API wxPython contém uma classe wx.Choice, cujo objeto também é uma lista suspensa, que é permanentemente somente leitura.

8 Wx.Gauge

O objeto de classe Wx.Gauge mostra uma barra vertical ou horizontal, que mostra graficamente a quantidade crescente.

9 wx.Slider

A API wxPython contém a classe wx.Slider. Oferece a mesma funcionalidade da barra de rolagem. O controle deslizante oferece uma maneira conveniente de arrastar a alça pelo fichário de evento wx.EVT_SLIDER específico do controle deslizante.

10 wx.MenuBar

Uma barra horizontal logo abaixo da barra de título de uma janela de nível superior é reservada para exibir uma série de menus. É um objeto da classe wx.MenuBar na API wxPython.

11 wx.Toolbar

Se o parâmetro de estilo do objeto wx.Toolbar for definido como wx.TB_DOCKABLE, ele se tornará encaixável. Uma barra de ferramentas flutuante também pode ser construída usando a classe AUIToolBar de wxPython.

12 Wx.Dialog

Embora um objeto de classe Dialog apareça como um Frame, ele normalmente é usado como uma janela pop-up no topo de um frame pai. O objetivo de um Diálogo é coletar alguns dados do usuário e enviá-los ao frame pai.

13 wx.Notebook

O widget wx.Notebook apresenta um controle com guias. Um objeto Notebook em um quadro possui uma ou mais guias (chamadas de Páginas), cada uma delas tendo um painel que mostra o layout dos controles.

14 wx.SplitterWindow

O objeto desta classe é um gerenciador de layout, que contém duas subjanelas cujo tamanho pode ser alterado dinamicamente arrastando os limites entre elas. O controle Divisor oferece uma alça que pode ser arrastada para redimensionar os controles.

15 HTMLWindow

A biblioteca wxHTML contém classes para analisar e exibir o conteúdo HTML. Embora este não seja um navegador completo, o objeto wx.HtmlWindow é um visualizador de HTML genérico.

16 ListBox e ListCtrl

Um widget wx.ListBox apresenta uma lista de strings que pode ser rolada verticalmente. Por padrão, um único item da lista é selecionável. O widget ListCtrl é uma ferramenta de exibição e seleção de lista altamente aprimorada. Uma lista de mais de uma coluna pode ser exibida na visualização Relatório, Visualização em lista ou Visualização de ícones.

Ao contrário de um aplicativo de modo de console, que é executado de maneira sequencial, um aplicativo baseado em GUI é orientado a eventos. Funções ou métodos são executados em resposta às ações do usuário, como clicar em um botão, selecionar um item da coleção ou clicar com o mouse, etc., chamados de eventos.

Os dados relativos a um evento que ocorre durante o tempo de execução do aplicativo são armazenados como objeto de uma subclasse derivada de wx.Event. Um controle de exibição (como Button) é a origem do evento de um tipo específico e produz um objeto da classe Event associado a ele. Por exemplo, clicar em um botão emite um wx.CommandEvent. Esses dados de evento são despachados para o método manipulador de eventos no programa. wxPython possui muitos ligadores de eventos predefinidos. AEvent binder encapsula o relacionamento entre um widget (controle) específico, seu tipo de evento associado e o método do manipulador de eventos.

Por exemplo, para ligar OnClick() method do programa em um evento de clique de botão, a seguinte declaração é necessária -

self.b1.Bind(EVT_BUTTON, OnClick)

Bind() methodé herdado por todos os objetos de exibição da classe wx.EvtHandler. EVT_.BUTTON aqui é o fichário, que associa o evento de clique de botão ao método OnClick ().

Exemplo

No exemplo a seguir, o MoveEvent, causado ao arrastar a janela de nível superior - um objeto wx.Frame, neste caso - está conectado a OnMove() methodusando o fichário wx.EVT_MOVE. O código exibe uma janela. Se for movido com o mouse, suas coordenadas instantâneas são exibidas no console.

import wx
  
class Example(wx.Frame): 
            
   def __init__(self, *args, **kw): 
      super(Example, self).__init__(*args, **kw)  
      self.InitUI() 
           
   def InitUI(self): 
      self.Bind(wx.EVT_MOVE, self.OnMove) 
      self.SetSize((250, 180)) 
      self.SetTitle('Move event') 
      self.Centre() 
      self.Show(True)
		   
   def OnMove(self, e): 
      x, y = e.GetPosition() 
      print "current window position x = ",x," y= ",y 
         
ex = wx.App() 
Example(None) 
ex.MainLoop()

O código acima produz a seguinte saída -

posição atual da janela x = 562 y = 309

posição atual da janela x = 562 y = 309

posição atual da janela x = 326 y = 304

posição atual da janela x = 384 y = 240

posição atual da janela x = 173 y = 408

posição atual da janela x = 226 y = 30

posição atual da janela x = 481 y = 80

Algumas das subclasses herdadas de wx.Event estão listadas na tabela a seguir -

SN Eventos e Descrição
1

wxKeyEvent

Ocorre quando uma tecla é pressionada ou liberada

2

wxPaintEvent

É gerado sempre que o conteúdo da janela precisa ser redesenhado

3

wxMouseEvent

Contém dados sobre qualquer evento devido à atividade do mouse, como botão do mouse pressionado ou arrastado

4

wxScrollEvent

Associado a controles de rolagem como wxScrollbar e wxSlider

5

wxCommandEvent

Contém dados de eventos originados de muitos widgets, como botão, caixas de diálogo, área de transferência, etc.

6

wxMenuEvent

Diferentes eventos relacionados ao menu, exceto clique do botão de comando

7

wxColourPickerEvent

eventos gerados por wxColourPickerCtrl

8

wxDirFilePickerEvent

Eventos gerados por FileDialog e DirDialog

Os eventos em wxPython são de dois tipos. Eventos básicos e eventos de comando. Um evento básico permanece local para a janela em que se origina. A maioria dos wxWidgets gera eventos de comando. UMAcommand event pode ser propagado para a janela ou janelas, que estão acima da janela de origem na hierarquia de classes.

Exemplo

A seguir está um exemplo simples de propagação de eventos. O código completo é -

import wx
  
class MyPanel(wx.Panel): 
     
   def __init__(self, parent): 
      super(MyPanel, self).__init__(parent)
		
      b = wx.Button(self, label = 'Btn', pos = (100,100)) 
      b.Bind(wx.EVT_BUTTON, self.btnclk) 
      self.Bind(wx.EVT_BUTTON, self.OnButtonClicked) 
		
   def OnButtonClicked(self, e): 
         
      print 'Panel received click event. propagated to Frame class' 
      e.Skip()  
		
   def btnclk(self,e): 
      print "Button received click event. propagated to Panel class" 
      e.Skip()
		
class Example(wx.Frame):

   def __init__(self,parent): 
      super(Example, self).__init__(parent)  
         
      self.InitUI() 

   def InitUI(self):
	
      mpnl = MyPanel(self) 
      self.Bind(wx.EVT_BUTTON, self.OnButtonClicked)
		
      self.SetTitle('Event propagation demo') 
      self.Centre() 
      self.Show(True)
		
   def OnButtonClicked(self, e): 
         
      print 'click event received by frame class' 
      e.Skip()
		
ex = wx.App() 
Example(None) 
ex.MainLoop()

No código acima, existem duas classes. MyPanel, uma subclasse wx.Panel e Exemplo, uma subclasse wx.Frame que é a janela de nível superior do programa. Um botão é colocado no painel.

Este objeto Button está vinculado a um manipulador de eventos btnclk () que o propaga para a classe pai (MyPanel neste caso). O clique de botão gera umCommandEvent que pode ser propagado para seu pai pelo método Skip ().

O objeto da classe MyPanel também vincula o evento recebido a outro manipulador OnButtonClicked (). Essa função, por sua vez, transmite para seu pai, a classe Example. O código acima produz a seguinte saída -

Button received click event. Propagated to Panel class. 
Panel received click event. Propagated to Frame class. 
Click event received by frame class.

Um widget GUI pode ser colocado dentro da janela do contêiner especificando suas coordenadas absolutas medidas em pixels. As coordenadas são relativas às dimensões da janela definidas pelo argumento de tamanho de seu construtor. A posição do widget dentro da janela é definida porpos argumento de seu construtor.

import wx  

app = wx.App() 
window = wx.Frame(None, title = "wxPython Frame", size = (300,200)) 
panel = wx.Panel(window) 
label = wx.StaticText(panel, label = "Hello World", pos = (100,50)) 
window.Show(True) 
app.MainLoop()

este Absolute Positioning no entanto, não é adequado pelos seguintes motivos -

  • A posição do widget não muda, mesmo se a janela for redimensionada.

  • A aparência pode não ser uniforme em dispositivos de exibição diferentes com resoluções diferentes.

  • A modificação no layout é difícil, pois pode ser necessário redesenhar todo o formulário.

A API wxPython fornece classes de layout para gerenciamento mais elegante do posicionamento de widgets dentro do contêiner. As vantagens dos gerenciadores de layout sobre o posicionamento absoluto são -

  • Os widgets dentro da janela são redimensionados automaticamente.
  • Garante aparência uniforme em dispositivos de exibição com diferentes resoluções.
  • Adicionar ou remover widgets dinamicamente é possível sem ter que redesenhar.

O gerenciador de layout é chamado de Sizer em wxPython. Wx.Sizer é a classe base para todas as subclasses de sizer. Vamos discutir alguns dos dimensionadores importantes, como wx.BoxSizer, wx.StaticBoxSizer, wx.GridSizer, wx.FlexGridSizer e wx.GridBagSizer.

SN Medidores e descrição
1 BoxSizer

Este dimensionador permite que os controles sejam organizados em linhas ou colunas. O layout do BoxSizer é determinado por seu argumento de orientação (wxVERTICAL ou wxHORIZONTAL).

2 GridSizer

Como o nome sugere, um objeto GridSizer apresenta uma grade bidimensional. Os controles são adicionados no slot da grade na ordem da esquerda para a direita e de cima para baixo.

3 FlexiGridSizer

Este dimensionador também possui uma grade bidimensional. No entanto, oferece um pouco mais de flexibilidade no layout dos controles nas células.

4 GridBagSizer

GridBagSizer é um dimensionador versátil. Ele oferece mais melhorias do que FlexiGridSizer. O widget filho pode ser adicionado a uma célula específica da grade.

5 StaticBoxSizer

Um StaticBoxSizer coloca um dimensionador de caixa em uma caixa estática. Ele fornece uma borda ao redor da caixa junto com uma etiqueta na parte superior.

O widget de botão é mais amplamente usado em qualquer interface GUI. Ele captura o evento de clique gerado pelo usuário. Seu uso mais óbvio é acionar uma função de tratamento associada a ele.

A biblioteca de classes wxPython fornece diferentes tipos de botões. Existe um botão simples e tradicional,wx.Buttonobjeto de classe, que carrega algum texto como legenda. Um botão de dois estados também está disponível, denominadowx.ToggleButton. Seu estado pressionado ou deprimido pode ser identificado pela função eventhandler.

Outro tipo de botão, wx.BitmapButton exibe um bitmap (imagem) como ícone em sua face.

O construtor para as classes wx.Button e wx.ToggleButton leva os seguintes argumentos -

Wx.Button(parent, id, label, pos, size, style)

Estes são alguns métodos importantes da classe wx.Button -

SN Métodos e Descrição
1

SetLabel()

Define a legenda do botão de maneira programática

2

GetLabel()

Retorna a legenda do botão

3

SetDefault()

O botão é definido como padrão para a janela de nível superior. Emula o evento de clique ao pressionar a tecla Enter

Dois métodos importantes da classe wx.ToggleButton são -

SN Métodos e Descrição
1

GetValue()

Retorna o estado do botão de alternância (liga / desliga)

2

SetValue()

Define o estado do botão de forma programática

Para criar um botão de bitmap, em primeiro lugar, um objeto de bitmap precisa ser construído a partir de um arquivo de imagem.

A seguinte variação do construtor da classe wx.Bitmap é mais comumente usada -

Wx.Bitmap(fiiename, wx.BITMAP_TYPE)

Algumas das constantes de tipo de bitmap predefinidas são -

wx.BITMAP_TYPE_BMP
wx.BITMAP_TYPE_ICO
wx.BITMAP_TYPE_CUR
wx.BITMAP_TYPE_TIFF
wx.BITMAP_TYPE_TIF
wx.BITMAP_TYPE_GIF
wx.BITMAP_TYPE_PNG
wx.BITMAP_TYPE_JPEG
wx.BITMAP_TYPE_PCX
wx.BITMAP_TYPE_ICON
wx.BITMAP_TYPE_ANY

Este objeto de bitmap é usado como um dos parâmetros para o construtor da classe wx.BitmapButton.

Wx.BitmapButton(parent, id, bitmap, pos, size, style)

Em algumas plataformas de sistema operacional, o botão de bitmap pode exibir bitmap e rótulo. Os métodos SetLabel () atribuem a legenda. Em outras plataformas, ele serve como um rótulo interno.

O botão normal e também o botão de bitmap emite um wx.CommandEvent. EVT_BUTTON binder associa uma função de manipulador a ele.

O botão de alternância, por outro lado, usa o fichário wx.TOGGLEBUTTON para manipulação de eventos.

No exemplo a seguir, os botões de todos os três tipos são colocados em um dimensionador de caixa vertical de um painel.

O objeto de botão simples é criado usando a instrução -

self.btn = wx.Button(panel, -1, "click Me")

O botão de alternância é construído pela seguinte declaração -

self.tbtn = wx.ToggleButton(panel , -1, "click to on")

Esses botões são adicionados ao dimensionador vertical usando as seguintes instruções -

vbox.Add(self.btn,0,wx.ALIGN_CENTER) 
vbox.Add(self.tbtn,0,wx.EXPAND|wx.ALIGN_CENTER)

Note - Por causa do sinalizador wx.EXPAND, o botão de alternância ocupa toda a largura do quadro.

Usando os fichários EVT_BUTTON e EVT_TOGGLEBUTTON, eles são associados aos respectivos manipuladores.

self.btn.Bind(wx.EVT_BUTTON,self.OnClicked) 
self.tbtn.Bind(wx.EVT_TOGGLEBUTTON,self.OnToggle)

Três botões de bitmap são adicionados a um dimensionador de caixa horizontal. Esses botões exibem uma imagem como ícone e legenda.

bmp = wx.Bitmap("NEW.BMP", wx.BITMAP_TYPE_BMP) 
self.bmpbtn = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp,
   size = (bmp.GetWidth()+10, bmp.GetHeight()+10))
  
bmp1 = wx.Bitmap("OPEN.BMP", wx.BITMAP_TYPE_BMP) 
self.bmpbtn1 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp1,
   size = (bmp.GetWidth()+10, bmp.GetHeight()+10))
  
bmp2 = wx.Bitmap("SAVE.BMP", wx.BITMAP_TYPE_BMP) 
self.bmpbtn2 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp2,
   size = (bmp.GetWidth()+10, bmp.GetHeight()+10))

O evento de clique desses três botões é direcionado ao método OnClicked ().

self.bmpbtn.Bind(wx.EVT_BUTTON, self.OnClicked) 
self.bmpbtn1.Bind(wx.EVT_BUTTON, self.OnClicked) 
self.bmpbtn2.Bind(wx.EVT_BUTTON, self.OnClicked)

Os rótulos internos desses botões são definidos como NOVO, ABRIR e SALVAR, respectivamente.

A função de manipulador de eventos OnClicked () recupera o rótulo do botão de origem, que causou o evento click. Essa etiqueta está impressa no console.

def OnClicked(self, event): 
   btn = event.GetEventObject().GetLabel() 
   print "Label of pressed button = ",btn

O manipulador de eventos OnToggle () é disparado quando o botão de alternância é clicado. Seu estado é lido pelo método GetValue () e, conseqüentemente, a legenda do botão é definida.

def OnToggle(self,event): 
   state = event.GetEventObject().GetValue() 
   if state == True: 
      print "off" 
      event.GetEventObject().SetLabel("click to off") 
   else: 
      print "on" 
      event.GetEventObject().SetLabel("click to on")

A lista de códigos completa é a seguinte -

import wx 
class Mywin(wx.Frame): 
   def __init__(self, parent, title): 
      super(Mywin, self).__init__(parent, title = title,size = (200,150))  
      panel = wx.Panel(self) 
      vbox = wx.BoxSizer(wx.VERTICAL) 
         
      self.btn = wx.Button(panel,-1,"click Me") 
      vbox.Add(self.btn,0,wx.ALIGN_CENTER) 
      self.btn.Bind(wx.EVT_BUTTON,self.OnClicked) 
         
      self.tbtn = wx.ToggleButton(panel , -1, "click to on") 
      vbox.Add(self.tbtn,0,wx.EXPAND|wx.ALIGN_CENTER) 
      self.tbtn.Bind(wx.EVT_TOGGLEBUTTON,self.OnToggle) 
         
      hbox = wx.BoxSizer(wx.HORIZONTAL) 
         
      bmp = wx.Bitmap("NEW.BMP", wx.BITMAP_TYPE_BMP) 
      self.bmpbtn = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp,
         size = (bmp.GetWidth()+10, bmp.GetHeight()+10)) 
			
      hbox.Add(self.bmpbtn,0,wx.ALIGN_CENTER) 
      self.bmpbtn.Bind(wx.EVT_BUTTON,self.OnClicked) 
      self.bmpbtn.SetLabel("NEW") 
         
      bmp1 = wx.Bitmap("OPEN.BMP", wx.BITMAP_TYPE_BMP) 
      self.bmpbtn1 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp1,
         size = (bmp.GetWidth()+10, bmp.GetHeight()+10)) 
			
      hbox.Add(self.bmpbtn1,0,wx.ALIGN_CENTER) 
      self.bmpbtn1.Bind(wx.EVT_BUTTON,self.OnClicked) 
      self.bmpbtn1.SetLabel("OPEN") 
         
      bmp2 = wx.Bitmap("SAVE.BMP", wx.BITMAP_TYPE_BMP) 
      self.bmpbtn2 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp2,
         size = (bmp.GetWidth()+10, bmp.GetHeight()+10))
			
      hbox.Add(self.bmpbtn2,0,wx.ALIGN_CENTER) 
      self.bmpbtn2.Bind(wx.EVT_BUTTON,self.OnClicked)
      self.bmpbtn2.SetLabel("SAVE") 
         
      vbox.Add(hbox,1,wx.ALIGN_CENTER) 
      panel.SetSizer(vbox) 
        
      self.Centre() 
      self.Show() 
      self.Fit()  
		
   def OnClicked(self, event): 
      btn = event.GetEventObject().GetLabel() 
      print "Label of pressed button = ",btn 
		
   def OnToggle(self,event): 
      state = event.GetEventObject().GetValue() 
		
      if state == True: 
         print "Toggle button state off" 
         event.GetEventObject().SetLabel("click to off") 
      else: 
         print " Toggle button state on" 
         event.GetEventObject().SetLabel("click to on") 
             
app = wx.App() 
Mywin(None,  'Button demo') 
app.MainLoop()

O código acima produz a seguinte saída -

Rótulo do botão pressionado = clique em mim

Desativar estado do botão

Ativar estado do botão

Rótulo do botão pressionado = NOVO

Rótulo do botão pressionado = ABRIR

Rótulo do botão pressionado = SALVAR

wxAuié uma biblioteca de interface de usuário avançada incorporada na API wxWidgets. Wx.aui.AuiManager a classe central na estrutura AUI.

AuiManagergerencia os painéis associados a um quadro específico usando as informações de cada painel no objeto wx.aui.AuiPanelInfo. Vamos aprender sobre as várias propriedades de encaixe e comportamento flutuante do controle de objeto PanelInfo.

Colocar janelas encaixáveis ​​na moldura de nível superior envolve as seguintes etapas -

Primeiro, crie um objeto AuiManager.

self.mgr = wx.aui.AuiManager(self)

Em seguida, um painel com os controles necessários é projetado.

pnl = wx.Panel(self) 
pbox = wx.BoxSizer(wx.HORIZONTAL) 
text1 = wx.TextCtrl(pnl, -1, "Dockable", style = wx.NO_BORDER | wx.TE_MULTILINE) 
pbox.Add(text1, 1, flag = wx.EXPAND) 
pnl.SetSizer(pbox)

Os seguintes parâmetros de AuiPanelInfo são definidos.

  • Direction - Superior, Inferior, Esquerda, Direita ou Centro

  • Position- Mais de um painel pode ser colocado dentro de uma região acoplável. Cada um recebe um número de posição.

  • Row- Mais de um painel aparece em uma linha. Exatamente como mais de uma barra de ferramentas aparecendo na mesma linha.

  • Layer - Os painéis podem ser colocados em camadas.

Usando este PanelInfo, o painel projetado é adicionado ao objeto gerenciador.

info1 = wx.aui.AuiPaneInfo().Bottom() 
self.mgr.AddPane(pnl,info1)

O resto da janela de nível superior pode ter outros controles, como de costume.

O código completo é o seguinte -

import wx 
import wx.aui
  
class Mywin(wx.Frame):
  
   def __init__(self, parent, title): 
      super(Mywin, self).__init__(parent, title = title, size = (300,300)) 
		
      self.mgr = wx.aui.AuiManager(self)
		
      pnl = wx.Panel(self) 
      pbox = wx.BoxSizer(wx.HORIZONTAL)
      text1 = wx.TextCtrl(pnl, -1, "Dockable", style = wx.NO_BORDER | wx.TE_MULTILINE) 
      pbox.Add(text1, 1, flag = wx.EXPAND) 
      pnl.SetSizer(pbox) 
         
      info1 = wx.aui.AuiPaneInfo().Bottom() 
      self.mgr.AddPane(pnl, info1) 
      panel = wx.Panel(self) 
      text2 = wx.TextCtrl(panel, size = (300,200), style =  wx.NO_BORDER | wx.TE_MULTILINE) 
      box = wx.BoxSizer(wx.HORIZONTAL) 
      box.Add(text2, 1, flag = wx.EXPAND) 
         
      panel.SetSizerAndFit(box) 
      self.mgr.Update() 
		
      self.Bind(wx.EVT_CLOSE, self.OnClose) 
      self.Centre() 
      self.Show(True) 
		
   def OnClose(self, event): 
      self.mgr.UnInit() 
      self.Destroy() 
		
app = wx.App()
Mywin(None,"Dock Demo")  
app.MainLoop()

O código acima produz a seguinte saída -

Um aplicativo GUI típico pode ter várias janelas. Os widgets com guias e empilhados permitem ativar uma janela por vez. No entanto, muitas vezes essa abordagem pode não ser útil, pois a visualização de outras janelas está oculta.

Uma maneira de exibir várias janelas simultaneamente é criá-las como janelas independentes. Isso é chamado de SDI (Single Document Interface) Isso requer mais recursos de memória, pois cada janela pode ter seu próprio sistema de menu, barra de ferramentas, etc.

A estrutura MDI em wxPython fornece uma classe wx.MDIParentFrame. Seu objeto atua como um contêiner para várias janelas filho, cada uma um objeto da classe wx.MDIChildFrame.

As janelas filho residem na área MDIClientWindow do quadro pai. Assim que um quadro filho é adicionado, a barra de menu do quadro pai mostra um menu Janela contendo botões para organizar os filhos em cascata ou lado a lado.

Exemplo

O exemplo a seguir ilustra os usos de MDIParentFrame como janela de nível superior. Um botão de Menu chamado NewWindow adiciona uma janela filha na área do cliente. Várias janelas podem ser adicionadas e organizadas em uma ordem em cascata ou lado a lado.

O código completo é o seguinte -

import wx 
 
class MDIFrame(wx.MDIParentFrame): 
   def __init__(self): 
      wx.MDIParentFrame.__init__(self, None, -1, "MDI Parent", size = (600,400)) 
      menu = wx.Menu() 
      menu.Append(5000, "&New Window") 
      menu.Append(5001, "&Exit") 
      menubar = wx.MenuBar() 
      menubar.Append(menu, "&File") 
		
      self.SetMenuBar(menubar) 
      self.Bind(wx.EVT_MENU, self.OnNewWindow, id = 5000) 
      self.Bind(wx.EVT_MENU, self.OnExit, id = 5001) 
		
   def OnExit(self, evt): 
      self.Close(True)  
		
   def OnNewWindow(self, evt): 
      win = wx.MDIChildFrame(self, -1, "Child Window")
      win.Show(True) 
		
app = wx.App() 
frame = MDIFrame() 
frame.Show() 
app.MainLoop()

O código acima produz a seguinte saída -

GDI+ (Interface de Desenho Gráfico), CoreGraphics e Cairo librariesformar a estrutura da API de desenho em wxPython. wx.GraphicsContext é o objeto drawable principal, usando o qual vários objetos de contexto de dispositivo são criados.

wx.DC é uma classe abstrata. Suas classes derivadas são usadas para renderizar gráficos e texto em diferentes dispositivos. As classes Device Context são -

  • wx.ScreenDC - Use para pintar na tela, em vez de uma janela individual.

  • wx.ClientDC - Use para pintar na área cliente da janela (a parte sem bordas e outras decorações), mas não use de dentro de um wxPaintEvent.

  • wx.PaintDC- Use para pintar na área do cliente da janela, mas apenas de dentro de um wxPaintEvent.

  • wx.WindowDC- Use para pintar em toda a área da janela, incluindo decorações. Isso pode não estar disponível em plataformas não Windows.

A API de desenho de wxPython oferece diferentes funções para desenhar formas, textos e imagens. Objetos necessários para fins de desenho, como Cor, Caneta, Pincel e Fonte também podem ser construídos usando classes GDI.

wx.Colour Class

O objeto de cor representa a combinação de valores de intensidade RGB (VERMELHO, Verde e Azul), cada um na escala de 0-255. Existem alguns objetos de cor predefinidos como -

  • wxBLACK
  • wxBLUE
  • wxCYAN
  • wxGREEN
  • wxYELLOW
  • wxLIGHT_GREY
  • wxRED
  • wxWHITE

A cor com combinação personalizada de valores RGB é formada como wx.Colour object.

wx.Colour(r,g,b)

classe wx.Pen

O objeto Caneta determina a cor, largura e estilo da forma dos gráficos, como linha, retângulo, círculo, etc.

Predefined Pen objects são -

wxBLACK_DASHED_PEN
wxBLACK_PEN
wxBLUE_PEN
wxCYAN_PEN
wxGREEN_PEN
wxYELLOW_PEN
wxGREY_PEN
wxLIGHT_GREY_PEN
wxMEDIUM_GREY_PEN
wxRED_PEN
wxTRANSPARENT_PEN
wxWHITE_PEN

Predefined Pen styles são -

wx.SOLID
wx.DOT
wx.LONG_DASH
wx.SHORT_DASH
wx.DOT_DASH
wx.TRANSPARENT

classe wx.Brush

Pincel é outro objeto gráfico elementar necessário para preencher os fundos de formas como retângulo, elipse, círculo, etc.

Um objeto Brush personalizado requer os parâmetros wx.Colour e Brush style. A seguir está uma lista de estilos de pincel predefinidos -

wx.SOLID
wx.STIPPLE
wx.BDIAGONAL_HATCH
wx.CROSSDIAG_HATCH
wx.FDIAGONAL_HATCH
wx.CROSS_HATCH
wx.HORIZONTAL_HATCH
wx.VERTICAL_HATCH
wx.TRANSPARENT

wxPython possui uma série de funções que facilitam o desenho de diferentes formas, texto e imagem.

SN Funções e descrição
1

DrawRectangle()

Desenha um retângulo com as dimensões fornecidas

2

DrawCircle()

Desenha um círculo no ponto determinado como centro e raio

3

DrawEllipse()

Desenha uma elipse com os raios xey dados

4

DrawLine()

Desenha uma linha entre dois objetos wx.Point

5

DrawBitmap()

Desenhe uma imagem na posição dada

6

DrawText()

Mostra o texto fornecido na posição especificada

Exemplo

As funções acima são implementadas no exemplo a seguir, fazendo uso de objetos Caneta, Pincel, Cor e Fonte.

O código completo é o seguinte -

import wx 
 
class Mywin(wx.Frame): 
            
   def __init__(self, parent, title): 
      super(Mywin, self).__init__(parent, title = title,size = (500,300))  
      self.InitUI() 
         
   def InitUI(self): 
      self.Bind(wx.EVT_PAINT, self.OnPaint) 
      self.Centre() 
      self.Show(True)
		
   def OnPaint(self, e): 
      dc = wx.PaintDC(self) 
      brush = wx.Brush("white")  
      dc.SetBackground(brush)  
      dc.Clear() 
        
      dc.DrawBitmap(wx.Bitmap("python.jpg"),10,10,True) 
      color = wx.Colour(255,0,0)
      b = wx.Brush(color) 
		
      dc.SetBrush(b) 
      dc.DrawCircle(300,125,50) 
      dc.SetBrush(wx.Brush(wx.Colour(255,255,255))) 
      dc.DrawCircle(300,125,30) 
		
      font = wx.Font(18, wx.ROMAN, wx.ITALIC, wx.NORMAL) 
      dc.SetFont(font) 
      dc.DrawText("Hello wxPython",200,10) 
		
      pen = wx.Pen(wx.Colour(0,0,255)) 
      dc.SetPen(pen) 
      dc.DrawLine(200,50,350,50) 
      dc.SetBrush(wx.Brush(wx.Colour(0,255,0), wx.CROSS_HATCH)) 
      dc.DrawRectangle(380, 15, 90, 60) 
		
ex = wx.App() 
Mywin(None,'Drawing demo') 
ex.MainLoop()

O código acima produz a seguinte saída -

Fornecimento de drag and dropé muito intuitivo para o usuário. É encontrado em muitos aplicativos de desktop onde o usuário pode copiar ou mover objetos de uma janela para outra apenas arrastando-o com o mouse e soltando em outra janela.

A operação de arrastar e soltar envolve as seguintes etapas -

  • Declarar um alvo de queda
  • Criar objeto de dados
  • Crie wx.DropSource
  • Executar operação de arrastar
  • Cancelar ou aceitar descartar

Em wxPython, existem dois destinos de soltar predefinidos -

  • wx.TextDropTarget
  • wx.FileDropTarget

Muitos widgets wxPython suportam atividade de arrastar e soltar. O controle de origem deve ter o arrasto ativado, enquanto o controle de destino deve estar em uma posição para aceitar (ou rejeitar) o arrasto.

Os dados de origem que o usuário está arrastando são colocados no objeto de destino. OnDropText () do objeto de destino consome os dados. Se desejar, os dados do objeto de origem podem ser excluídos.

Exemplo

No exemplo a seguir, dois objetos ListCrl são colocados horizontalmente em um Box Sizer. A lista à esquerda é preenchida com dados de idiomas []. É designado como fonte de arrasto. Um à direita é o alvo.

languages = ['C', 'C++', 'Java', 'Python', 'Perl', 'JavaScript', 'PHP', 'VB.NET','C#'] 
self.lst1 = wx.ListCtrl(panel, -1, style = wx.LC_LIST) 
self.lst2 = wx.ListCtrl(panel, -1, style = wx.LC_LIST) 

   for lang in languages: 
      self.lst1.InsertStringItem(0,lang)

O segundo controle de lista está vazio e é um argumento para objeto da classe TextDropTarget.

class MyTextDropTarget(wx.TextDropTarget):
   def __init__(self, object): 
      wx.TextDropTarget.__init__(self) 
      self.object = object
		
   def OnDropText(self, x, y, data): 
      self.object.InsertStringItem(0, data)

O método OnDropText () adiciona dados de origem no controle de lista de destino.

A operação de arrastar é inicializada pelo fichário de eventos.

wx.EVT_LIST_BEGIN_DRAG(self, self.lst1.GetId(), self.OnDragInit)

A função OnDragInit () coloca os dados de arrastar no destino e exclui da fonte.

def OnDragInit(self, event): 
   text = self.lst1.GetItemText(event.GetIndex()) 
   tobj = wx.PyTextDataObject(text) 
   src = wx.DropSource(self.lst1) 
   src.SetData(tobj) 
   src.DoDragDrop(True) 
   self.lst1.DeleteItem(event.GetIndex())

O código completo é o seguinte -

import wx
  
class MyTarget(wx.TextDropTarget): 
   def __init__(self, object): 
      wx.TextDropTarget.__init__(self) 
      self.object = object  
		
   def OnDropText(self, x, y, data): 
      self.object.InsertStringItem(0, data)  
		
class Mywin(wx.Frame): 
            
   def __init__(self, parent, title): 
      super(Mywin, self).__init__(parent, title = title,size = (-1,300))   
      panel = wx.Panel(self) 
      box = wx.BoxSizer(wx.HORIZONTAL)  
      languages = ['C', 'C++', 'Java', 'Python', 'Perl', 'JavaScript',
         'PHP', 'VB.NET','C#']
			
      self.lst1 = wx.ListCtrl(panel, -1, style = wx.LC_LIST) 
      self.lst2 = wx.ListCtrl(panel, -1, style = wx.LC_LIST) 
      for lang in languages: 
      self.lst1.InsertStringItem(0,lang) 
             
      dt = MyTarget(self.lst2) 
      self.lst2.SetDropTarget(dt) 
      wx.EVT_LIST_BEGIN_DRAG(self, self.lst1.GetId(), self.OnDragInit)
		
      box.Add(self.lst1,0,wx.EXPAND) 
      box.Add(self.lst2, 1, wx.EXPAND) 
		
      panel.SetSizer(box) 
      panel.Fit() 
      self.Centre() 
      self.Show(True)  
     
   def OnDragInit(self, event): 
      text = self.lst1.GetItemText(event.GetIndex()) 
      tobj = wx.PyTextDataObject(text) 
      src = wx.DropSource(self.lst1) 
      src.SetData(tobj) 
      src.DoDragDrop(True) 
      self.lst1.DeleteItem(event.GetIndex()) 
		
ex = wx.App() 
Mywin(None,'Drag&Drop Demo') 
ex.MainLoop()

O código acima produz a seguinte saída -