Aller au contenu
Top-Metin2.org - Vous êtes à la recherche d'un serveur Metin 2 ? ×
×
×
  • Créer...

Python - Créer une GUI


Messages recommandés

  • Robot

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.

  • Love 8

french_banner.gif

Lien vers le commentaire
Partager sur d’autres sites

  • 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

Lien vers le commentaire
Partager sur d’autres sites

  • Robot

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.

french_banner.gif

Lien vers le commentaire
Partager sur d’autres sites

  • 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 ! :)

Lien vers le commentaire
Partager sur d’autres sites

  • Robot

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.

french_banner.gif

Lien vers le commentaire
Partager sur d’autres sites

  • 9 mois après...

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 ;)

Lien vers le commentaire
Partager sur d’autres sites

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

Lien vers le commentaire
Partager sur d’autres sites

  • 2 semaines après...

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 :) .

Modifié par Zed
  • Love 1
Lien vers le commentaire
Partager sur d’autres sites



  • brilliantdiscord_widget
  • Flux d'Activité

    1. 37
    2. 21

      Metin2 en 2020 peut-on en parler?

    3. 0

      METIN2Project

    4. 3

      Ressources - UnPack - Metin2 Client - Officiel

    5. 0

      Barre des tâches d'argent étendue

    6. 16

      Redémarrage automatique des channels

    7. 16

      Multi Logo GM / SGM / GA

  • En ligne récemment

    • Aucun utilisateur enregistré regarde cette page.

Information importante

Conditions d’utilisation / Politique de confidentialité / Règles / Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer.