Wo bleibt mein Text?

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
Cruzer
User
Beiträge: 11
Registriert: Sonntag 5. Juli 2009, 18:36

Ich habe begonnen mit Python 2.6 ein kleines Pseudo3D Spiel mit Comic mäßigen Grafiken mithilfe PyGame zu schreiben. (Screenshot hier: http://img216.imageshack.us/i/opencity001.png/) Das darstellen der Spielkarte und deren Gebäude ist kein Problem und funktioniert auch schon. Selbst ein funktionierenter Cursor und ein simples Event-System exestiert bereits. Nun sollte eine kleine InGame GUI kommen. Jedoch scheitere ich zurzeit daran, Texte auszugeben.
Meine erste Klasse für die GUI soll ein PopUpMenu sein. Also ein Menü, welches z.B.: beim drücken der rechten Maustaste erscheint, irgendetwas stimmt jedoch nicht. Denn ich sehe denn Text nicht.

Hier die Klasse "PopUpMenu":

Code: Alles auswählen

import pygame, pygame.mouse
from pygame.locals import *
from message import *

class PopUpMenu():
    x = 0
    y = 0
    __width = 0
    backcolor = (192,192,192)
    forcolor = (122,122,122)

    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.__width = 220
        self.__entry = list()
        self.font = pygame.font.Font(None, 12)
        self.linesize = self.font.get_linesize()

    def render(self, screen):
        x = self.x
        y = self.y
        box = pygame.rect.Rect(x, y, self.__width, (self.linesize+4) * len(self.__entry) + 4)
        # Zuerst zeichne den Hintergrund
        pygame.draw.rect(screen, self.backcolor, box)
        # Dann zeichne den Rahmen
        pygame.draw.rect(screen, self.forcolor, box, 1)
        # Und nun den Text auf eine Surface schreiben.
        for entry in self.__entry:
            text = self.font.render(entry[1], 0, self.forcolor)
            text.blit(screen, (x+2,y+3))
            y = y + self.linesize + 4
            

    def addEntry(self, entry_id, text, icon=None):
        self.__entry.append((entry_id, text, icon))
        # Bei jedem hinzufügen eines Textes, wird geprüft ob der neu Text größer ist, als
        #  der bissher breiteste Text. Sollte dies der Fall sein, so wird das graue
        #  Hintergrundfeld des PopUpMenus vergroessert.
        (text_width, text_height) = self.font.size(text)
        if self.__width < text_width + 6:
            self.__width = text_width + 6
Um die Klasse zu verwenden, wird sie folgend aufgerufen:

Code: Alles auswählen

menu = PopUpMenu(10,20)
menu.addEntry(1,"Hallo Welt!")
menu.addEntry(2, "Und tschuess!")
menu.render(screen)
Wobei "screen" das Surface des Bildschirmes ist.

Ist übrigens mein erstes größeres Python Programm, also seit bitte milde zu mir, sollte ich irgendeinen Mist gedreht haben.
Ich hoffe ihr findet meinen Fehler.



Danke,
Cruzer


Nachtrag:
Auf dem oben erwöhnten Screenshot sieht man ausserdem das Ergebnis dieser Klasse. (Am linken oberen Eck des Screenshots) Es ist eine leere graue Box.
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Hier ist Dein Text:
http://paste.pocoo.org/show/129922/

Statt "text.blit(screen, ..." muss es "screen.blit(text, ..." heissen.

Bitte poste demnaechst ein komplettes(!) Programm, das foerdert die Neigung, sich damit auseinanderzusetzen, enorm.

:wink:
yipyip
Cruzer
User
Beiträge: 11
Registriert: Sonntag 5. Juli 2009, 18:36

Danke. Ja jetzt funktionierts.
Ok. Sollte ich mal wieder Hilfe brauchen, stelle ich das ganze Programm herein.
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Ich meinte natuerlich ein komplettes Programm auf das Notwendigste (zur Fehlersuche) beschraenkt.
:wink:
yipyip
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Dein Quelltext ist unidiomatisch.

Sternchen-Importe sollten vermieden werden. PopUpMenu ist keine New Style KIasse (erbt von object, das muss man in Python 2.6 noch beachten, in >= 3.0 nicht mehr). Warum schreibst du die Definitionen von x, y samt Rest in den Klassenkörper? Dadurch werden es Klassenvariablen. Diese überschreibst du aber sowieso sobald du ein Exemplar erstellst. Besser wäre zb soetwas:

Code: Alles auswählen

class A(object):
    def __init__(self, x=0, y=0):
         self.x, self.y = x, y
         # ...
Sofern du Standardwerte willst, natürlich.

Doppelunterstriche braucht man nur in wenigen Fällen. Willst du eine Instanzvariable als "privat" markieren, kannst du einen einzelnen Unterstrich benutzen. Das ist aber eine Konvention; es gibt keinen richtigen "private" Mechanismus.

Warum erstellst du deine Box immer neu? Du könntest den ganzen x y width Kram doch gleich als Rect speichern. Die ganzen Zahlen solltest du zumindest kommentieren.

Generell solltest du dir mal das Python Tutorial auf docs.python.org anschauen.
Antworten