Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 01/05/2008, à 13:19

Arrrakis

wxPython dessiner quadrillage dans un panel

bonjour,
en wxPython, je cherche la manière la plus simple pour dessiner un quadrillage dans un panel et de colorier les carrés avec les couleurs souhaitées. Qu'elle serait le widget à utilisé selon vous?
je pars d'une matrice: ( par exemple)

[ 2 0 1 ]
[ 1 1 2 ]
[ 2 0 1 ]

et colorié:
les 0 en noir
les 1 en rouge
les 2 en jaune

ma vraie matrice allant jusqu'à 400*400.
merci, cordialement

Hors ligne

#2 Le 01/05/2008, à 18:24

robrob

Re : wxPython dessiner quadrillage dans un panel

Je vois 2 solutions:
- dessiner de manière bourrine (en définissant un wxPanel custom)
- créer une image, image affichage avec un contrôle du type wxStaticBitmap

Pour définir une fonction de dessin personnalisé (en C++)
- ajouter un évenement EVT_PAINT dans la table des événements
- définir sa fonction de dessin

BEGIN_EVENT_TABLE(my_panel, wxPanel)
	EVT_PAINT(my_panel::paint)
END_EVENT_TABLE()

my_panel::my_panel(wxWindow* parent, wxWindowID id)
	: wxPanel(parent, id, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE)
{
	// rien
}

void my_panel::paint(wxPaintEvent& /*event*/)
{
	wxPaintDC dc(this);
	wxSize dim=GetClientSize();

	// on dessine ce que l'on veut par exemple un rectangle rouge avec un contour noir
	dc.Clear();
	dc.SetPen(*wxBLACK_PEN);
	dc.SetBrush(*wxRED_BRUSH);
	dc.DrawRectangle(10,10,dim.GetWidth()-20,dim.GetHeight()-20);

	dc.SetBrush(wxNullBrush);
	dc.SetPen(wxNullPen);
}

Dans mon exemple, il y a une petite subtilité. Dans la mesure où ma fonction de dessin est dépendante de la taille du panel, il est nécessaire de demander à wxWidgets de redessiner l'intégralité du panel en cas de redimensionnement. C'est le rôle de wxFULL_REPAINT_ON_RESIZE dans le constructeur.

Quelques remarques importantes pour finir:
- le wxPaintDC dc(this); est obligatoire sans le programme crash...sous windows lol
- si tu veux un rectangle (ou un cercle ou n'importe quel autre forme proposée) sans remplissage il faut utiliser wxTRANSPARENT_BRUSH comme wxBrush.
- de même pour ne pas avoir de contour, il existe wxTRANSPARENT_PEN.
- à la fin du dessin il est important de déselectionner les outils de dessin utilisés (wxPen, wxBrush éventuellement wxFont). C'est le role des SetBrush(wxNullBrush) et SetPen(wxNullPen).

Pour créer une image (en C++)
Il faut utiliser l'objet wxImage (plus pratique wxBitmap).
- création d'une instance de wxImage de la taille de la matrice
- coloriage de l'image en fonction des valeurs de la matrice
Puis l'affichage de se fera avec un wxStaticBitmap + une conversion du wxImage en wxBitmap.

wxImage image(400,400);

for(int y=0;y<400;y++)
	for(int x=0;x<400;x++)
	{
		switch (matrice[x][y])
		{
			case 0:
				image.SetRGB(x,y,255,0,0);
				break;
			case 1:
				image.SetRGB(x,y,255,127,0);
				break;

			[...]

			case default:
				image.SetRGB(x,y,0,0,0);
		}
	}

wxStaticBitmap image_ctrl = new wxStaticBitmap(this, wxID_ANY, wxBitmap(image));

A toi d'adapter en wxPyhton wink

Dernière modification par robrob (Le 01/05/2008, à 18:24)

Hors ligne

#3 Le 06/05/2008, à 13:04

J-berne

Re : wxPython dessiner quadrillage dans un panel

bonjour c'est re-moi mais sous mon compte, merci robrob pour ton post. J'ai un peu de mal à traduire ça en wxPython.
Par exemple le code:
wxImage image(400,400);
En wxPython l'init de wx.Image est :
wx.Image.__init__(parent, nom.jpeg(ou bmp ou ...), type=wxBITMAP_TYPE_BMP(ou autre), identifiant)
On ne peux pas instancier une wx.image juste avec taille, et puis qque autre petit truc. donc si qqu'un peut traduire ça en wxPython se serait sympa.
Merci, cordialement.
J-Berne


Le savoir est la seul chose qui augmente quand on le partage.
J'aimerai bien changer le monde, mais pas moyen de mettre la main sur le code source ...

Hors ligne

#4 Le 06/05/2008, à 14:48

J-berne

Re : wxPython dessiner quadrillage dans un panel

sinon il n'existe pas un objet aussi simple que tk.Canvas mais en wx???????


Le savoir est la seul chose qui augmente quand on le partage.
J'aimerai bien changer le monde, mais pas moyen de mettre la main sur le code source ...

Hors ligne

#5 Le 06/05/2008, à 19:17

robrob

Re : wxPython dessiner quadrillage dans un panel

Tu as create qui devrait faire l'affaire:
http://www.wxpython.org/docs/api/wx.Image-class.html#Create

en effet:

wxImage image(400,400);

revient au même que

wxImage image;
image.create(400,400);

En revanche, désolé, mais je n'ai jamais fait ni de python ni de tk sad

Dernière modification par robrob (Le 06/05/2008, à 19:18)

Hors ligne

#6 Le 06/05/2008, à 21:53

bipede

Re : wxPython dessiner quadrillage dans un panel

Arrrakis a écrit :

bonjour,
en wxPython, je cherche la manière la plus simple pour dessiner un quadrillage dans un panel et de colorier les carrés avec les couleurs souhaitées. Qu'elle serait le widget à utilisé selon vous?
je pars d'une matrice: ( par exemple)

[ 2 0 1 ]
[ 1 1 2 ]
[ 2 0 1 ]

et colorié:
les 0 en noir
les 1 en rouge
les 2 en jaune

ma vraie matrice allant jusqu'à 400*400.
merci, cordialement

je ferais ça tout simplement avec des wx.Window

#!/usr/bin/env python
#-*- coding: utf-8 -*-

import wx

matrice = [[2, 0, 1], [1, 1, 2], [2, 0, 1]]

class MyPiece(wx.Window):
	def __init__(self, parent, color):
		wx.Window.__init__(self, parent=parent, id=-1, size=(30,30))
		if color == 0:
			self.color=wx.BLACK
		elif color == 1:
			self.color=wx.RED
		else:
			self.color=wx.GREEN
		self.SetBackgroundColour(self.color)
		
class MyFrame(wx.Frame):
	def __init__(self):
		wx.Frame.__init__(self, parent=None, id=-1, title=u"Matrice")
		box = wx.BoxSizer(wx.VERTICAL)
		panel = wx.Panel(self, -1)
		sizer1 = wx.BoxSizer(wx.VERTICAL)
		sizer2 = wx.GridSizer(3, 3, 2, 2)
		for x in matrice:
			for y in x:
				sizer2.Add(MyPiece(panel, y), 0)
		sizer1.Add(sizer2, 0, wx.ALIGN_CENTRE|wx.ALL, border=40)
		panel.SetSizer(sizer1)
		sizer1.Fit(panel)
		box.Add(panel, 1, wx.EXPAND)
		self.SetSizer(box)
		self.Fit()
		
		self.Bind(wx.EVT_CLOSE, self.OnClose)
		
	def OnClose(self, event):
		self.Destroy()
		
class MyApp(wx.App):
	def OnInit(self):
		frame = MyFrame()
		self.SetTopWindow(frame)
		frame.Show()
		return True

app = MyApp()
app.MainLoop()

Desktop: MSI - Intel® Core™ i5-3330 CPU @ 3.00GHz × 4 - RAM 8 go- Kubuntu 21.04 - Système sur SSD 64 Go - /home sur HDD 500 Go.
Laptop: DELL Inspiron-15 3567 - Intel® Core™ i5-7200 CPU @ 2.50GHz × 4 - RAM 8 go - HDD 1 To - Ubuntu 20.10 avec /home séparé.

Mon site: Les contributions du bipède

Hors ligne