Tkinter Canvas mit Farbverlauf

Code-Stücke können hier veröffentlicht werden.
Antworten
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo Forumfreunde

Ich habe mich mit Farbverläufen auf Canvas-Widgets beschäftigt. Hier entstand eine Klasse mit der Canvasflächen eingefärbt werden können. Sicher gibt es noch bessere Lösungen. Ich wollte eimal von der monotonen Malerei auf ein wenig Kunst umsteigen Hi. Das ganze kann sicher noch optimiert und erweitert werden.

Habe den Code getestet mit:

Python 2.4
SuSE 10.0
Windows XP

Hier der Code:

[Code ausgelagert]

Gruss wuf :wink: [/url]
Take it easy Mates!
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Mal wieder:

Code: Alles auswählen

        if fade_direction == 'fade_up':
            line_nr   = self.height -1
            line_max  = self.height

        elif fade_direction == 'fade_down':
            line_nr   = 0
            line_max  = self.height

        elif fade_direction == 'fade_left':
            line_nr   = self.width -1
            line_max  = self.width

        elif fade_direction == 'fade_right':
            line_nr   = 0
            line_max  = self.width

        else:
            line_nr   = self.height-1
            line_max  = self.height

# würde ich so schreiben:
        try:
            line_nr, line_max = {
                'fade_up'   : (self.height -1, self.height),
                'fade_down' : (0, self.height),
                'fade_left' : (self.width -1, self.width),
                'fade_right': (0, self.width),
            }[fade_direction]
        except KeyError:
            line_nr, line_max = self.height-1, self.height
Mein üblicher Vorschlag ;)


Ebenso hier:

Code: Alles auswählen

           if fade_color == 'gray':
                color_tuple = (ptr,ptr,ptr)
            elif fade_color == 'blue':
                color_tuple = (0,0,ptr)
            elif fade_color == 'green':
                color_tuple = (0,ptr,0)
            elif fade_color == 'red':
                color_tuple = (ptr,0,0)
            elif fade_color == 'cyan':
                color_tuple = (0,ptr,ptr)
            elif fade_color == 'yellow':
                color_tuple = (ptr,ptr,0)
            elif fade_color == 'purple':
                color_tuple = (ptr,0,ptr)
            elif fade_color == 'lightgreen':
                color_tuple = (0,255,ptr)
            elif fade_color == 'yellowred':
                color_tuple = (255,ptr,0,)
            elif fade_color == 'purpleblue':
                color_tuple = (ptr,0,255)
            elif fade_color == 'lightred':
                color_tuple = (255,0,ptr,)
            elif fade_color == 'lightblue':
                color_tuple = (0,ptr,255)
            elif fade_color == 'greenyellow':
                color_tuple = (ptr,255,0)
            elif fade_color == 'lightyellow':
                color_tuple = (255,255,ptr)
            elif fade_color == 'lightpurple':
                color_tuple = (255,ptr,255)
            elif fade_color == 'lightcyan':
                color_tuple = (ptr,255,255)
            else:
                color_tuple = (ptr,ptr,ptr)
# refactored:
            try:
                color_tuple = {
                    'gray'        : (ptr,ptr,ptr),
                    'blue'        : (0,0,ptr),
                    'green'       : (0,ptr,0),
                    'red'         : (ptr,0,0),
                    'cyan'        : (0,ptr,ptr),
                    'yellow'      : (ptr,ptr,0),
                    'purple'      : (ptr,0,ptr),
                    'lightgreen'  : (0,255,ptr),
                    'yellowred'   : (255,ptr,0,),
                    'purpleblue'  : (ptr,0,255),
                    'lightred'    : (255,0,ptr,),
                    'lightblue'   : (0,ptr,255),
                    'greenyellow' : (ptr,255,0),
                    'lightyellow' : (255,255,ptr),
                    'lightpurple' : (255,ptr,255),
                    'lightcyan'   : (ptr,255,255),
                }[fade_color]
            except KeyError:
                color_tuple = (ptr,ptr,ptr)
Und hier:

Code: Alles auswählen

            if fade_direction == 'fade_up':
                #~~ Farbaufhellung von unten nach oben
                self.create_line(
                    0,line_nr,
                    self.width,line_nr,
                    fill = line_color,
                    )
                line_nr -= 1

            elif fade_direction == 'fade_down':
                #~~ Farbaufhellung von oben nach unten
                self.create_line(
                    0,line_nr,
                    self.width,line_nr,
                    fill = line_color,
                    )
                line_nr += 1

            elif fade_direction == 'fade_left':
                #~~ Farbaufhellung von links nach rechts
                self.create_line(
                    line_nr,0,
                    line_nr,self.height,
                    fill = line_color,
                    )
                line_nr -= 1

            elif fade_direction == 'fade_right':
                #~~ Farbaufhellung von rechts nach links
                self.create_line(
                    line_nr,0,
                    line_nr,self.height,
                    fill = line_color,
                    )
                line_nr += 1

            else:
                #~~ Farbaufhellung von unten nach oben
                self.create_line(
                    0,line_nr,
                    self.width,line_nr,
                    fill = line_color,
                    )
                line_nr-= 1
# Refactored:
            try:
                args, inc = {
                    'fade_up': #~~ Farbaufhellung von unten nach oben
                            ((0,line_nr,
                            self.width,line_nr,
                            fill = line_color),-1),
                    'fade_down': #~~ Farbaufhellung von oben nach unten
                            ((0,line_nr,
                            self.width,line_nr,
                            fill = line_color),+1),
                    'fade_left': #~~ Farbaufhellung von links nach rechts
                            ((line_nr,0,
                            line_nr,self.height,
                            fill = line_color),-1),
                    'fade_right': #~~ Farbaufhellung von rechts nach links
                            ((line_nr,0,
                            line_nr,self.height,
                            fill = line_color),+1),
                }[fade_direction]
            except KeyError:
                args, inc = \
                    ((0,line_nr,
                    self.width,line_nr,
                    fill = line_color),-1)

            line_nr += inc
            self.create_line(*args)
Vim Recordings sind so unglaublich toll \o/

Übrigens fände ich "right", "up", "down", etc. besser als "fade_right", "fade_up"..der Name des Arguments "fade_direction" sollte hinweis genug geben was das sein soll ;)
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo audax

Besten Dank für deine Anregungen. Ich finde die Optimierungen Super!

Gruss wuf :wink:
Take it easy Mates!
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Was mir gerade aufgefallen ist, man das default statement auch schöner schreiben:

Code: Alles auswählen

            color_tuple = {
                'gray'        : (ptr,ptr,ptr),
                'blue'        : (0,0,ptr),
                'green'       : (0,ptr,0),
                'red'         : (ptr,0,0),
                'cyan'        : (0,ptr,ptr),
                'yellow'      : (ptr,ptr,0),
                'purple'      : (ptr,0,ptr),
                'lightgreen'  : (0,255,ptr),
                'yellowred'   : (255,ptr,0,),
                'purpleblue'  : (ptr,0,255),
                'lightred'    : (255,0,ptr,),
                'lightblue'   : (0,ptr,255),
                'greenyellow' : (ptr,255,0),
                'lightyellow' : (255,255,ptr),
                'lightpurple' : (255,ptr,255),
                'lightcyan'   : (ptr,255,255),
            }.get(fade_color, 
                color_tuple = (ptr,ptr,ptr) )
Ehrlich gesagt finde ich den Python-Switch-Case so wesentlich besser als den echten C-like. Ich ertappe mich schon dabei, wie ich den in Java einsetze :D
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo audax

Ich habe deine vorgeschlagenen Code-Fragmente in mein Skript integriert und es wieder zum laufen gebracht. Gewisse Teile deines Codes wollten aber nicht funktionieren.

Teil-1 Dein Code-Fragment:

Code: Alles auswählen

            color_tuple = {
                'gray'        : (ptr,ptr,ptr),
                'blue'        : (0,0,ptr),
                'green'       : (0,ptr,0),
                'red'         : (ptr,0,0),
                'cyan'        : (0,ptr,ptr),
                'yellow'      : (ptr,ptr,0),
                'purple'      : (ptr,0,ptr),
                'lightgreen'  : (0,255,ptr),
                'yellowred'   : (255,ptr,0,),
                'purpleblue'  : (ptr,0,255),
                'lightred'    : (255,0,ptr,),
                'lightblue'   : (0,ptr,255),
                'greenyellow' : (ptr,255,0),
                'lightyellow' : (255,255,ptr),
                'lightpurple' : (255,ptr,255),
                'lightcyan'   : (ptr,255,255),
            }.get(fade_color,
                color_tuple = (ptr,ptr,ptr) )
Meine Änderung (Zeile 19,20):

Code: Alles auswählen

            }.get(fade_color, (ptr,ptr,ptr) )
Teil-2 Dein Code-Fragment:

Code: Alles auswählen

            try:
                args, inc = {
                    'fade_up': #~~ Farbaufhellung von unten nach oben
                            ((0,line_nr,
                            self.width,line_nr,
                            fill = line_color),-1),
                    'fade_down': #~~ Farbaufhellung von oben nach unten
                            ((0,line_nr,
                            self.width,line_nr,
                            fill = line_color),+1),
                    'fade_left': #~~ Farbaufhellung von links nach rechts
                            ((line_nr,0,
                            line_nr,self.height,
                            fill = line_color),-1),
                    'fade_right': #~~ Farbaufhellung von rechts nach links
                            ((line_nr,0,
                            line_nr,self.height,
                            fill = line_color),+1),
                }[fade_direction]
            except KeyError:
                args, inc = \
                    ((0,line_nr,
                    self.width,line_nr,
                    fill = line_color),-1)

            line_nr += inc
            self.create_line(*args)
Meine Änderungen:

Code: Alles auswählen

            args,fill,inc = {
                'fade_up':    #~~ Farbaufhellung von unten nach oben
                        ((0,line_nr,self.width,line_nr),line_color,-1),
                'fade_down':  #~~ Farbaufhellung von oben nach unten
                        ((0,line_nr,self.width,line_nr),line_color,+1),
                'fade_left':  #~~ Farbaufhellung von links nach rechts
                        ((line_nr,0,line_nr,self.height),line_color,-1),
                'fade_right': #~~ Farbaufhellung von rechts nach links
                        ((line_nr,0,line_nr,self.height),line_color,+1),
            }.get(fade_direction,((0,line_nr,self.width,line_nr),line_color,-1))


            line_nr += inc
            self.create_line(
                args,
                fill = line_color
                )
Bei diesem Code-Fragment habe ich try: except: entfernt. Lerneffekt aus deiner letzten Änderung. Hi.

Die Canvas-Grafik-Methode w.create_line(....) muss als erstes Argument eine Liste oder Tuple mit einer geraden Anzahl von Koordinaten-Punkte erhalten, danach kommen die Optionen. Die Argument-Übergabe mit *args machte somit Probleme.

Auch folgende Tuple-Konstellation machte Probleme:

Code: Alles auswählen

                            ((0,line_nr,
                            self.width,line_nr,
                            fill = line_color),-1),
Hier war es nach Aussage des Tracebacks folgendes Element:

fill = line_color

OK audax nochmals vielen Dank für deine Vorschläge die mich auf eine höher Ebene der Python-Programmierung katapultierten. Hi.

Ich wollte mein neues Skript auf dem Pocoo-Paste-Server deponieren dieser aber weigerte sich etwas entgegenzunehmen. Vielleicht hat er zu heiss. Ich werde dies nachholen sobald er wieder abgekühlt ist.

Beste Grüsse von wuf :wink:
Take it easy Mates!
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Na da hat der Stups ja ganz gut was gebracht :]
Gern geschehen jedenfalls!

Ps:
Die Fehler waren natürlich nur zur Übung enthalten ;)
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo audax

Hier noch mein modifiziertes Code-Snippet. Die Integration deiner Code-Fragmente brachten eine beachtliche Code-Reduktion. Ich machte noch ein Bechmark-Test zum Orginal, welcher eine leicht erhöhte vernachlässigbare Abarbeitungszeitzunahme von 12% zeigte.

[Code ausgelagert]

Ich musste den Code auf einen anderen Paste-Server auslagern, da der Pocoo-Paste-Server seine Dienst gegenüber mir immer noch verweigert. Er hat scheinbar auch Schwierigkeiten Umlaute zu verdauen. Wobei Englisch eigendlich nicht die einzige Sprache auf dieser Welt ist.Hi.

Gruss wuf :wink:
Take it easy Mates!
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Das ständige erstellen der dicts könnte es sein..aber da müsste nen Profiler ran. Evtl. könnte man einige der dicts auslagern, oder zumindest effizienter erstellen.

Aber nun, 12% sind in dem Fall ja auch nicht die Welt...
Antworten