Jump to content
×
×
  • Create New...

Python - Créer une GUI


Recommended Posts

  • Bot

Bonjour.

 

Ayant fait un ancien tutoriel pour créer des gui de A à Z, je vais vous proposez ici une manière un peu plus facile de les faire.

 

Une petite explication s'impose :

On va passer par des selfs à chaque fois. Je vais vous donner une class, avec tous les éléments principaux et vous pourrez les définir et les placer comme je vais vous expliquer ci-dessous.

 

Créez un fichier Python, par exemple : takuma.py

Dans ce fichier, commencez par ajouter cette structure :

import ui
import dbg
import app

class Dialog1(ui.Window):
def __init__(self):
	ui.Window.__init__(self)
	self.BuildWindow()

def __del__(self):
	ui.Window.__del__(self)

def BuildWindow(self):
	self.Board = ui.BoardWithTitleBar()
	self.Board.SetSize(170, 170)
	self.Board.SetCenterPosition()
	self.Board.AddFlag('movable')
	self.Board.AddFlag('float')
	self.Board.SetTitleName('Window')
	self.Board.SetCloseEvent(self.Close)
	self.Board.Show()
	self.__BuildKeyDict()
	self.comp = Component()


def __BuildKeyDict(self):
	onPressKeyDict = {}
	onPressKeyDict[app.DIK_F5]	= lambda : self.OpenWindow()
	self.onPressKeyDict = onPressKeyDict

def OnKeyDown(self, key):
	try:
		self.onPressKeyDict[key]()
	except KeyError:
		pass
	except:
		raise
	return TRUE

def OpenWindow(self):
	if self.Board.IsShow():
		self.Board.Hide()
	else:
		self.Board.Show()

def Close(self):
	self.Board.Hide()

class Component:
def Button(self, parent, buttonName, tooltipText, x, y, func, UpVisual, OverVisual, DownVisual):
	button = ui.Button()
	if parent != None:
		button.SetParent(parent)
	button.SetPosition(x, y)
	button.SetUpVisual(UpVisual)
	button.SetOverVisual(OverVisual)
	button.SetDownVisual(DownVisual)
	button.SetText(buttonName)
	button.SetToolTipText(tooltipText)
	button.Show()
	button.SetEvent(func)
	return button

def ToggleButton(self, parent, buttonName, tooltipText, x, y, funcUp, funcDown, UpVisual, OverVisual, DownVisual):
	button = ui.ToggleButton()
	if parent != None:
		button.SetParent(parent)
	button.SetPosition(x, y)
	button.SetUpVisual(UpVisual)
	button.SetOverVisual(OverVisual)
	button.SetDownVisual(DownVisual)
	button.SetText(buttonName)
	button.SetToolTipText(tooltipText)
	button.Show()
	button.SetToggleUpEvent(funcUp)
	button.SetToggleDownEvent(funcDown)
	return button

def EditLine(self, parent, editlineText, x, y, width, heigh, max):
	SlotBar = ui.SlotBar()
	if parent != None:
		SlotBar.SetParent(parent)
	SlotBar.SetSize(width, heigh)
	SlotBar.SetPosition(x, y)
	SlotBar.Show()
	Value = ui.EditLine()
	Value.SetParent(SlotBar)
	Value.SetSize(width, heigh)
	Value.SetPosition(1, 1)
	Value.SetMax(max)
	Value.SetLimitWidth(width)
	Value.SetMultiLine()
	Value.SetText(editlineText)
	Value.Show()
	return SlotBar, Value

def TextLine(self, parent, textlineText, x, y, color):
	textline = ui.TextLine()
	if parent != None:
		textline.SetParent(parent)
	textline.SetPosition(x, y)
	if color != None:
		textline.SetFontColor(color[0], color[1], color[2])
	textline.SetText(textlineText)
	textline.Show()
	return textline

def RGB(self, r, g, b):
	return (r*255, g*255, b*255)

def SliderBar(self, parent, sliderPos, func, x, y):
	Slider = ui.SliderBar()
	if parent != None:
		Slider.SetParent(parent)
	Slider.SetPosition(x, y)
	Slider.SetSliderPos(sliderPos / 100)
	Slider.Show()
	Slider.SetEvent(func)
	return Slider

def ExpandedImage(self, parent, x, y, img):
	image = ui.ExpandedImageBox()
	if parent != None:
		image.SetParent(parent)
	image.SetPosition(x, y)
	image.LoadImage(img)
	image.Show()
	return image

def ComboBox(self, parent, text, x, y, width):
	combo = ui.ComboBox()
	if parent != None:
		combo.SetParent(parent)
	combo.SetPosition(x, y)
	combo.SetSize(width, 15)
	combo.SetCurrentItem(text)
	combo.Show()
	return combo

def ThinBoard(self, parent, moveable, x, y, width, heigh, center):
	thin = ui.ThinBoard()
	if parent != None:
		thin.SetParent(parent)
	if moveable == TRUE:
		thin.AddFlag('movable')
		thin.AddFlag('float')
	thin.SetSize(width, heigh)
	thin.SetPosition(x, y)
	if center == TRUE:
		thin.SetCenterPosition()
	thin.Show()
	return thin

def Gauge(self, parent, width, color, x, y):
	gauge = ui.Gauge()
	if parent != None:
		gauge.SetParent(parent)
	gauge.SetPosition(x, y)
	gauge.MakeGauge(width, color)
	gauge.Show()
	return gauge

def ListBoxEx(self, parent, x, y, width, heigh):
	bar = ui.Bar()
	if parent != None:
		bar.SetParent(parent)
	bar.SetPosition(x, y)
	bar.SetSize(width, heigh)
	bar.SetColor(0x77000000)
	bar.Show()
	ListBox=ui.ListBoxEx()
	ListBox.SetParent(bar)
	ListBox.SetPosition(0, 0)
	ListBox.SetSize(width, heigh)
	ListBox.Show()
	scroll = ui.ScrollBar()
	scroll.SetParent(ListBox)
	scroll.SetPosition(width-15, 0)
	scroll.SetScrollBarSize(heigh)
	scroll.Show()
	ListBox.SetScrollBar(scroll)
	return bar, ListBox

Dialog1().Show()
 

Vous pouvez aussi retrouver ce code avec les tabulations ici : https://pastebin.com/kCxM71DE

 

Sinon, faites un copier/coller et remplacez 4 espaces par une tabulation.

 

Bien, je vous ai presque entièrement fais le travail...

 

 

Changez la touche pour ouvrir la gui ici :

onPressKeyDict[app.DIK_F5]	= lambda : self.OpenWindow()
Retrouvez la taille de la fenêtre :
self.Board.SetSize(170, 170)
Retrouvez le nom de la fenêtre ici :
self.Board.SetTitleName('Window')
Pour les test, je vous conseille de laisser le :
Dialog1().Show()
Cela va vous permettre de directement ouvrir la fenêtre une fois import dans un fichier, supprimez le si vous voulez l'ouvrir avec un bouton, et utilisez la méthode au dessus.

 

Toute la class component, n'y touchez pas, c'est là ou j'ai mis toute la gestion des items à mettre sur la gui.

Donc à partir de :

class Component:
 

Jusqu'à la fin du fichier.

 

Bien, maintenant on voit comment ajouter quelque chose ?

 

Pour ajouter un bouton, dans la make window, ajoutez: 

self.de = self.comp.Button(self.Board, 'Déconnexion', '', 10, 294, self.de_func, 'd:/ymir work/ui/public/middle_button_01.sub', 'd:/ymir work/ui/public/middle_button_02.sub', 'd:/ymir work/ui/public/middle_button_03.sub')
Par exemple, ce bouton va créer un bouton avec le texte "Déconnexion" de coordonnées (10;294), exécutant la fonction "de-func" et on a ensuite la texture du bouton.

 

Vous ajoutez ensuite cette fonction, par exemple :

	def de_func(self):
	pass
 

Ici, cette fonction ne fait rien, mais vous pouvez très bien faire :

	def de_func(self):
	import chat
	net.SendChatPack("/logout")
Aucun problème là dessus.

 

Vous pouvez par exemple ajouter du texte, dans le make windows :

self.text = self.comp.TextLine(self.Board, 'Channels', 108, 33, self.comp.RGB(255, 255, 255))
On créer ici une ligne de texte avec écrit "Channels" en coordonnées (108;33) et de couleur RGB(255, 255, 255)

Assez simple non ?

 

Par exemple, pour ajouter une barre pour entrer des valeurs (input) :

self.slotbar_Input, self.Input = self.comp.EditLine(self.Board, '', 143, 41, 60, 15, 10)
Avec à la fin les coordonnées, la taille, et le nombre de caractère maximal.

Je vous laissez consulter les self pour le reste des éléments.

 

Si vous avez des questions, je peux y répondre sans problème.

 

Cordialement, Takuma.

  • J'adore 8

090100logo.png 090149logo-4-bis.png

Link to comment
  • Funkiest

Salut !

 

Merci à toi pour ce partage / tutoriel, je t'avoue que quand je dois créer des GUI je dois facilement repack une centaine de fois mon uiscript pour bien calculer les tailles au pixel près et j'en passe ! C'est assez long x)

Je pensais que tu allais parler du GuiCreator, qui est très pratique, bien que là encore je ne puisse l'utiliser :/

 

Petite précision (c'est du chipotage, t'as géré) :

 

-Si tu appelles ton bouton "Déconnexion" dans le Takuma.py, je doute qu'il affiche "Déconnexion", étant donné que la majeure partie du temps, l'UTF-8 n'est pas supporté et du coup il faut soit ruser, soit utiliser le bon vieux locale_interface/game.txt ! (Oui c'est assez embêtant)

-Là mon avis ne concerne que moi, mais j'ai plutôt tendance à déferrer les GUI dans le uiScript tandis que je code le python (fonctions & autres) dans le root, histoire de séparer les deux, mais c'est pas spécialement une précision étant donné que là tu parles de comment faire une GUI simplement en apportant le gros "bunddle" utile à tout ça !

 

Merci de ton investissement, ça fait plaisir ! +1

Link to comment
  • Bot

Je sais pas... maintenant perso je fais tout en un seul fichier comme ça.... Il me semble pour ton problème de repack, si tu mets les fichiers avec le exeils sont pris en compte... a vérifier. Cela vient peut être de mon client a moi :

 

Cordialement, Takuma.

090100logo.png 090149logo-4-bis.png

Link to comment
  • Funkiest

Oui, il n'y a pas non plus besoin de repacker pour changer les interfaces, il y a juste à reload le client ou reload les py par la console, ce que je disais c'était qu'il me fallait, à la main et à l'oeil, beaucoup d'essais pour que ça me convienne parfaitement ! :)

Link to comment
  • Bot

Pour le GuiEditor, sinon je partage le miens.. Je vais voir :3

Il propose 2 ou 3 truc de plus que celui que j'ai partagé, je vais voir ça^^' Pour l'autre guiEditor, il suffit d'import :o

La mienne permet bientôt l'édition en jeu.. Il me reste quelques trucs à faire :)^^'

 

 

Cordialement, Takuma.

090100logo.png 090149logo-4-bis.png

Link to comment
  • 9 months later...

C'est des coordonnées (x;y) classique ;)

Sauf prendre un GuiEditor (je crois que j'en ai partagé un), tu y arriveras un peu mieux avec l'habitude (genre retenir l'espace à mettre en ordonnées entre les boutons etc...). Je crois pas qu'il existe de solution magique, il faut le faire pour y s'entrainer ;)

Link to comment
Le 5/22/2017 à 22:30, Galet a dit :

Salut !

 

Merci à toi pour ce partage / tutoriel, je t'avoue que quand je dois créer des GUI je dois facilement repack une centaine de fois mon uiscript pour bien calculer les tailles au pixel près et j'en passe ! 

 

La base haha

Link to comment
  • 2 weeks later...

Salut à toi, et merci du partage.

 

Personnellement, sachant que le python est un langage objet, j'aime bien faire mes classes (ici GUI) de manière sémantiquement identique (ici on a une sémantique d'entité), je m'explique:

  • Je sais que toutes les classes de dialogues seront sensiblements les mêmes à quelques exceptions près, donc: Je fais une classe de base: BaseDialog et ensuite j'y met tous les attributs sémantiques de mes classes de dialogues (les services principaux) (là encore on pourrait dire que c'est ce que le ui.Window fait, mais le ui.Window est une classe qui se veut générale pour toutes les fenêtres, donc également pour tous les dialogues, mais rajouter une indirection ne fait pas de mal, car on respecte les principes SOLID: https://en.wikipedia.org/wiki/SOLID_(object-oriented_design) ).
  • Je fais une classe DialogXX pour chaque dialogue que j'ai besoin

 

@Galet Pour la gestion des pixels, personnellement je préfère passer par des fichiers externes dans le packs plutôt que le hard-coded stuff, ça me permet de tout centraliser et d'avoir, ainsi, un moyen rapide et scalable de gérer mes UI

 

C'était à titre purement informatif et juste une autre manière de concevoir la chose :) .

Edited by Zed
  • J'adore 1
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Flux d'Activité

    1. 2

      Site internet (CMS) compatible avec tous les emulateurs 1.29 (Azuriom)

    2. 2

      Site internet (CMS) compatible avec tous les emulateurs 1.29 (Azuriom)

    3. 84

      Granny

    4. 32

      Rodnia.net | PVM | International | The Great Conqueror |

    5. 16

      Map The OpenWorld Metin2

    6. 0
    7. 6

      [V2]Gurgarath Resurgence

  • Recently Browsing

    • No registered users viewing this page.

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.