GuiDesigner mit zahlreichen Hilfeseiten

Fragen zu Tkinter.
Antworten
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

GuiDesigner mit zahlreichen Hilfeseiten auf Github: https://github.com/AlfonsMittelmeyer/py ... -messaging

Außerdem Image Einbindung, Cursorauswahlfenster, Großes Textfenster, LinkLabel, LinkButton, eigene Klassen, nun auch tkinter kompatibles Exportformat mit Namen
kodela
User
Beiträge: 185
Registriert: Montag 12. Oktober 2015, 21:24
Wohnort: Landsberg am Lech
Kontaktdaten:

Hallo,

gibt es dazu auch so etwas wie eine Beschreibung?

MfG, kodela
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

@kodela Die Beschreibung ist in den Hilfeseiten. Die bekommt man im Menü unter Help. Wie er gestartet wird steht auch auf GitHub, nämlich mit python3 main.py

Beispiele zur Programmierung von Callbacks, etwa mit command oder bind fehlen noch. Sollte man eigentlich selber wissen. Aber für Anfänger wären sie nützlich, außerdem gäbe es auch noch ein paar nützliche zusätzliche Funktionen, die ich beschreiben sollte, wie virtuelle Events.

Dann wäre Version 1.0 fertig.
Das wäre aber nur tkinter ohne ttk.

Geplante Folgeversionen:

- Canvas Painting
- ttk Widgets
- XML Format
kodela
User
Beiträge: 185
Registriert: Montag 12. Oktober 2015, 21:24
Wohnort: Landsberg am Lech
Kontaktdaten:

Hallo Alfons Mittelmeyer,

na, so einfach ist das nicht. Das Verwirrspiel fängt mit der README.md an. Warum muss man sich da erst schlau machen, für welchen Dateityp die Extension "md" steht. Lässt man Windows danach suchen, bekommt man folgende Auskunft:
Dateityp: Mayura Draw-Zeichnung

Dateierweiterung: .md
Beschreibung: Diese Datei enthält eine Mayura Draw-Zeichnung

Glaubt man das nicht und öffnet die Datei über das Kontextmenü mit Notepad++, dann entpuppt sie sich als reine Textdatei. Warum kannst Du für eine simple Textdatei nicht auch die gängige Extension "txt" verwenden.

Danach habe ich die Datei "intro.py" gestartet und das ist das Ergebnis:

Code: Alles auswählen

C:\Tools\python-gui-messaging-master\GuiDesigner>python
Python 3.5.0 (v3.5.0:374f501f4567, Sep 13 2015, 02:16:59) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> intro
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'intro' is not defined
>>>
Versucht man es mit "main.py", dann sieht es genau so aus:

Code: Alles auswählen

>>> main
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'main' is not defined
>>>
Auch mit Angabe der Extension "py" ändert sich daran nichts. Da kommt keine große Freude auf.

MfG, kodela
BlackJack

@kodela: `*.md` ist die richtige Dateiendung für Textdateien die mit Markdown-Syntax ausgezeichnet sind. Wenn man die nicht so nennt würde Github sie beispielsweise nicht als solche erkennen und nicht entsprechend rendern. Das gilt auch für Alternativen wie Bitbucket. Wenn Du dem Link aus dem ersten Beitrag folgst, wird der Inhalt der Datei ja unter Dateiliste dargestellt und Überschrift und Aufzählung entsprechend mit den entsprechenden HTML-Auszeichnungen dargestellt. Wenn die Endung das allgemeinere `*.txt` wäre, dann würde das nicht passieren. Ein vernünftiges Betriebssystem beziehungsweise ein vernünftiger Dateimanager identifiziert Dateien auch nicht nur an der Dateiendung sondern schaut im Zweifelsfall in die Datei hinein und stellt dann fest das es sich um eine Textdatei handelt und bietet dann zum öffnen einen Texteditor an.

Der Versuch das Programm zu starten ist schlicht falsch und hat nichts mit dem Programm zu tun. *So* wirst Du *kein* Python-Programm starten können. ``python main.py`` ist etwas anderes als ``python[Return-Taste]main``.
kodela
User
Beiträge: 185
Registriert: Montag 12. Oktober 2015, 21:24
Wohnort: Landsberg am Lech
Kontaktdaten:

Hallo @BlackJack:

Danke für die Aufklärung bezüglich der Textdateien mit Markdown-Syntax Auszeichnung. Da muss ich mich morgen einmal schlau machen, was genau damit gemeint ist. Allerdings hat doch Github mit dieser Datei nichts mehr zu tun, wenn sie bei mir auf der Festplatte ist. Ich habe sie ja nicht über den Browser geöffnet, sondern das ganze Paket heruntergeladen.

Was Du zum Start der Python-Programme sagst, dass ich *So* *kein* Python-Programm starten könne, verstehe ich allerdings nicht, ich habe so, also in der Konsole zum Programmordner navigiert, dann Python gestartet und in der Eingabeaufforderung von Python den Dateinamen angegeben und dann läuft das Programm, nicht aber die Dateien aus dem GuiDesigner Paket. Oder habe ich Dich falsch verstanden?

MfG, kodela
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Deine Ausfuehrung zum Programmstart kann nicht stimmen. Du greifst so *immer* auf den Namen `intro` zu, den es natuerlich nicht gibt, darum der `NameError`.

Wenn du uns nicht glaubst, zitiere ich mal die Dokumentation: Dort wird es im Tutorial und in in der Usage Dokumentation beschrieben.

Readme Dateien haben fuer Github eben eine besondere Bedeutung und werden gerendert dargestellt und das will man ja auch haben schliesslich siehst du das _bevor_ du es auf deine eigene Festplatte herunterladen kannst. Die Wikipedia bietet fuer Markdown einen ganz brauchbaren Einstieg: https://de.wikipedia.org/wiki/Markdown

@BlackJack: Du haettest wohl nie erwartet, dass du mal Alfons verteidigst hm? :twisted:
kodela
User
Beiträge: 185
Registriert: Montag 12. Oktober 2015, 21:24
Wohnort: Landsberg am Lech
Kontaktdaten:

Hallo @cofi: hallo @BlackJack:

ich glaube Euch und cofi hat völlig Recht, meine Ausfuehrung zum Programmstart kann nicht stimmen. Ich habe allerdings auch nicht geschrieben, dass ich BlackJack nicht glauben würde, da ist mein Respekt vor seiner Kompetenz in Sachen Python viel zu groß. Ich habe lediglich geschrieben, dass ich es nicht verstünde und mittlerweile ist mir klar, dass es wohl die späte Stunde war, zu der ich meine Antwort geschrieben habe, die mein Denken doch sehr negativ beeinflusst hat.

Ich muss jetzt vorsichtig sein, dass ich nicht wieder "Käse" schreibe, aber letzte Nacht habe ich in auch versucht, die Dateien zum GuiDesigner unter Windows von der Konsole aus per Doppelklick zu starten und das funktionierte nicht. Es funktionierte dagegen mit meinen Dateien. Ich habe das jetzt eben noch einmal nachvollzogen und es hat sich mir bestätigt.

Entschuldigt bitte, dass ich Euch durch meine Aussage unnötige Schreibarbeit gemacht habe.

Mittlerweile funktioniert auch der Start der GuiDesigner-Dateien. Man ist eben im Vorteil, wenn man erst genau liest, was zu einem Thema geschrieben wurde.

MfG, kodela
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Alfons
Habe deinen letzten GuiDesigner(68) von GitHub heruntergeladen und damit Versuche mit dem Canvas-Widget unternommen. Da gibt es die Option scrollregion. Diese Option muss dem Widget als Tuple übergeben werden. Bei der Eingabe für die Option scrollregion (Im Rahmen configuration) wird die Tuple-Notation nicht angenommen. Also wenn du den Wert bestehend aus vier Zahlen in Klammern eingibst wird nach der Bestätigung mit Enter das Eingabefeld wieder geleert. Wenn ich aber den Wert für scrollregion mit vier diskreten Zahlen getrennt mit Space ohne Klammern wird die Eingabe angenommen. Beim exportieren des Projektes als Tk with names wird aber der Wert für die Option scrollregion mit den vier Zahlen im Configuration-Dictionary nur als String ohne Klammern zugewiesen.

Code: Alles auswählen

tk.Canvas(self,name = 'canvas',**{'bg': '#4682b4', 'highlightthickness': '0', 'scrollregion': '0 0 1000 500'})
Hier haben wir das gleiche Problem wie damals mit padx & pady für den Widget-Layout z.B.:
padx = (1, 2)

Gruss wuf :wink:
Take it easy Mates!
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Hi wuf, freut mich mal wieder etwas von Dir zu hören.

Hatte bisher bei den Config Options geklappt, dass ich die in einen String umwandle:

Code: Alles auswählen

for n,e in dictionaryConfig.items(): dictionaryConfig[n] = str(e)
Muss dann eben dasselbe tun, wie bei den Layout Options, nämlich nur Tcl Objekte in einen String umwandeln. Eine Referenz als Adresse ausgeben nützt nichts, daher eine solche umwandeln. Was kein Tcl Object ist, das kann man wahrscheinlich so lassen. wie es ist. Bei den Layout Optionen habe ich es so gemacht:

Code: Alles auswählen

for n,e in layoutDict.items():
    if class_type(type(e)) == "Tcl_Obj":
        layoutDict[n] = str(e)
Muss ich dann bei den Config Optionen auch so machen. Und dann ist natürlich zu testen, ob das reicht oder ob noch mehr davon umzuwandeln ist, und was genau und was nicht, bzw. vielleicht auch nur, was nicht - etwa int, string und tuple oder nur tuple

Und danke, dass Du das so genau untersuchst.

Gruss Alfons :wink:
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Hi wuf,

in diesem Falle aber ist es doch kein Fehler. Bei padx war ja das Problem, dass das als String mit einem tuple als Inhalt geschrieben wurde. Und dass dann das natürlich nicht funktionieren konnte.

In diesem Falle aber wird das nicht als tuple geschrieben. Das ist das, was im tkinter Config Dictionary steht, und damit ist es richtig, sofern tkinter das auch so wieder annimmt.

Dass man im Eingabefeld ein Tuple eingeben kann, welches dann mit eval ausgeführt wird, das muss nicht sein. Wenn tkinter intern einen String mit den Parametern durch Leerzeichen getrennt hat, und den auch so annimmt, sollte doch nichts dagegen einzuwenden sein, oder?
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Hi wuf, hab es mir nochmals angesehen. Da stimmt tatsächlich etwas nicht. Denn diese Eingabe wird angenommen: 10 20 30 40
Danach gibt tkinter bei meiner tkinter Version aber das zurück: ('10', '20', '30', '40')
Und das wird dann bei mir bei der Eingabe nicht mehr angenommen.
Und gespeichert wird bei mir das: Canvas('canvas',**{'scrollregion': "('10', '20', '30', '40')"}).grid(**{'row': '0'})

Es liegt bei meiner tkinter Version also ein Fehler vor - nicht bei tkinter - sondern beim GuiDesigner, der das tuple nicht behandelt - sollte dann im Eingabefeld auch beim Rücklesen ein String mit Parametern durch Leerzeichen getrennt werden und beim Schreiben ein tuple bleiben.

Bei Deiner Version funktioniert es aber anscheinend richtig, wenn tkinter das dann intern als String mit Parametern durch Leerzeichen getrennt hat.

Also ist dann doch etwas zu tun. Und diesmal kann ich es selber untersuchen, weil jetzt bei meiner tkinter Version dieser Fehler auftritt.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Alfons

Danke für deine Erläuterungen und Hinweise. Habe einmal versucht ein bestehendes Modul mit Hilfe deines GuiDesigner zu erstellen. Das Modul ist eine scrollbare Canvas. Hier folgt das bestehende Skript:
fws_scrolled_canvas_with_pack_01.py

Code: Alles auswählen

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

from functools import partial

try:
    # Tkinter for Python 2.xx
    import Tkinter as tk
    import ttk
except:
    # Tkinter for Python 3.xx
    import tkinter as tk
    from tkinter import ttk

APP_TITLE = "No GuiDesigner supported design"
APP_XPOS = 100
APP_YPOS = 100

CANVAS_WIDTH = 400
CANVAS_HEIGHT = 400
SCROLL_WIDTH = 1000
SCROLL_HEIGHT = 1000


class CanvasFrame(tk.Frame):
    def __init__(self, parent, width=CANVAS_WIDTH, height=CANVAS_HEIGHT,
        scroll_width=SCROLL_WIDTH, scroll_height=SCROLL_HEIGHT, *args,
        **kwargs):

        self.parent = parent
        
        tk.Frame.__init__(self, parent, *args, **kwargs)

        yscrollbar_frame = tk.Frame(self)
        yscrollbar_frame.pack(side='top', fill='both', expand=True)
        
        yscrollbar = tk.Scrollbar(yscrollbar_frame, orient='vertical',
            highlightthickness=0, bd=0, elementborderwidth=1)
        yscrollbar.pack(side='right', fill='y')

        xscrollbar_frame = tk.Frame(self)
        xscrollbar_frame.pack(side='top', fill='x')
        
        xscrollbar = tk.Scrollbar(xscrollbar_frame, orient='horizontal',
            highlightthickness=0, bd=0, elementborderwidth=1)
        xscrollbar.pack(side='left', fill='x', expand=True)

        corner_frame = tk.Frame(xscrollbar_frame, width=yscrollbar['width'])
        corner_frame.pack(side='left')
        
        self.canvas = tk.Canvas(yscrollbar_frame,width=width, height=height,
            xscrollcommand=xscrollbar.set, yscrollcommand=yscrollbar.set,
            highlightthickness=0, bg='green', scrollregion=(
            0, 0, scroll_width, scroll_height))
        self.canvas.pack(side='left', fill='both', expand=True)

        xscrollbar.config(command=self.canvas.xview)
        yscrollbar.config(command=self.canvas.yview)

       
class Application(tk.Frame):

    def __init__(self, master):
        self.master = master
        tk.Frame.__init__(self, master)

        self.canvas_frame = CanvasFrame(self, bg='yellow')
        self.canvas_frame.pack(side='left', fill='both') #, expand=True)
 
        self.canvas_frame.canvas.create_line(0, 0, 1000, 1000, fill='yellow',
            width=2, arrowshape=(20,21,5), arrow='both')


def main():
    app_win = tk.Tk()
    app_win.title(APP_TITLE)
    app_win.geometry("+{}+{}".format(APP_XPOS, APP_YPOS))
    #app_win.geometry("{}x{}".format(APP_WIDTH, APP_HEIGHT))
    
    app = Application(app_win).pack(side='left', fill='both', expand=True,
        padx=0, pady=0)
    
    app_win.mainloop()
 
 
if __name__ == '__main__':
    main()
Das folgende Skript erstellte ich mit deinem GuiDesigner und speicherte es als Projekskript ab:
scrollable_canvas_03.gui

Code: Alles auswählen

config(**{'title': 'GuiDesigner supported design'})

Frame('main_frame')
goIn()

Frame('bottom_frame')
goIn()

Frame('corner_frame',**{'height': '11', 'width': '11'})
Scrollbar('xscrollbar',**{'elementborderwidth': '1', 'bd': '0', 'orient': 'horizontal'})

widget('xscrollbar').pack(**{'fill': 'x', 'side': 'left', 'expand': 1})
widget('corner_frame').pack(**{'fill': 'both', 'side': 'left'})

goOut()

Frame('top_frame')
goIn()

Canvas('canvas',**{'height': '400', 'bg': '#4682b4', 'width': '400', 'scrollregion': '0 0 1000 1000', 'highlightthickness': '0'})
Scrollbar('yscrollbar',**{'elementborderwidth': '1', 'bd': '0'})

widget('canvas').pack(**{'side': 'left'})
widget('yscrollbar').pack(**{'fill': 'y', 'side': 'left'})

goOut()


widget('top_frame').pack(**{'fill': 'both'})
widget('bottom_frame').pack(**{'fill': 'x'})

goOut()


widget('main_frame').pack(**{'fill': 'both', 'expand': 1})
Habe das Projekt mittels Tk without names aus dem GuiDesigner exportiert:
(ACHTUNG: In diesem Skript kommentierte ich drei Zeilen aus um es für meinen Einsatz zu verwenden!)
scrollable_canvas_03.py

Code: Alles auswählen

import tkinter as tk
#import DynTkExtend as ext

class Application(tk.Tk):

    def __init__(self,**kwargs):
        tk.Tk.__init__(self,**kwargs)
        self.title('GuiDesigner supported design')
        self.main_frame = MainFrame(self)
        self.main_frame.pack(**{'fill': 'both', 'expand': 1})

class MainFrame(tk.Frame):

    def __init__(self,master,**kwargs):
        tk.Frame.__init__(self,master,**kwargs)
        self.bottom_frame = BottomFrame(self)
        self.top_frame = TopFrame(self)
        self.top_frame.pack(**{'fill': 'both'})
        self.bottom_frame.pack(**{'fill': 'x'})

class BottomFrame(tk.Frame):

    def __init__(self,master,**kwargs):
        tk.Frame.__init__(self,master,**kwargs)
        self.corner_frame = tk.Frame(self,**{'height': '11', 'width': '11'})
        self.xscrollbar = tk.Scrollbar(self,**{'elementborderwidth': '1', 'bd': '0', 'orient': 'horizontal'})
        self.xscrollbar.pack(**{'fill': 'x', 'side': 'left', 'expand': 1})
        self.corner_frame.pack(**{'fill': 'both', 'side': 'left'})

class TopFrame(tk.Frame):

    def __init__(self,master,**kwargs):
        tk.Frame.__init__(self,master,**kwargs)
        #self.canvas = tk.Canvas(self,**{'height': '400', 'bg': '#4682b4', 'width': '400', 'scrollregion': '0 0 1000 1000', 'highlightthickness': '0'})
        self.canvas = tk.Canvas(self,**{'height': '400', 'bg': '#4682b4', 'width': '400', 'scrollregion': (0, 0, 1000, 1000), 'highlightthickness': '0'})
        self.yscrollbar = tk.Scrollbar(self,**{'elementborderwidth': '1', 'bd': '0'})
        self.canvas.pack(**{'side': 'left'})
        self.yscrollbar.pack(**{'fill': 'y', 'side': 'left'})

#Application().mainloop()
Nun folgt mein Hauptskript, welches das von deinem GuiDesigner exportierte Skript importiert und verwendet:
main_scrollable_canvas_03.py

Code: Alles auswählen

from scrollable_canvas_03 import *

my_app = Application()

canvas = my_app.main_frame.top_frame.canvas
yscrollbar = my_app.main_frame.top_frame.yscrollbar
xscrollbar = my_app.main_frame.bottom_frame.xscrollbar

canvas.config(xscrollcommand=xscrollbar.set,
    yscrollcommand=yscrollbar.set)

xscrollbar.config(command=canvas.xview)
yscrollbar.config(command=canvas.yview)

canvas.create_line(0, 0, 1000, 1000, fill='yellow', width=2, arrowshape=(20,21,5),
    arrow='both')

my_app.mainloop()
OK Ich weiss nicht ob mein Vorgehen richtig war? Oder wie würdest du das vom GuiDesigner exportierte Skript in dein eigenes Projektskript einbinden?

N.B. Sorry, dass ich die obigen Skripte nicht in einer nummerierten Codebox präsentierte. Nach einer halben Stunde herumspielen warf ich die Flinte erfolglos ins Korn. Der tag [Codebox]Dein Code[/Codebox] scheint bei mir nicht zu funktionien. Vielleicht kannst du oder ein Moderator mir hierfür einen Tipp geben.

Gruss wuf :wink:
Take it easy Mates!
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Hi wuf,

schau es mir morgen an. Heute wird es wahrscheinlich leider nichts mehr. Habe soeben das mit den korrigierten tuples auf Github gestellt und mit entspechender Hilfe im Help Menü.

Gruss Alfons :wink:
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Hi wuf, habe es mir kurz angeschaut. Naja, so war es eigentlich nicht gedacht. Sondern export war als main script gedacht, zu dem man etwas dazumachen kann und es eigentlich nicht importiert.

Aber es hat funktioniert. Die Farbe war anders - blau statt grün, aber die hattest Du auch anders erfaßt. Was ich allerdings nicht verstehe ist das:

Code: Alles auswählen

        #self.canvas = tk.Canvas(self,**{'height': '400', 'bg': '#4682b4', 'width': '400', 'scrollregion': '0 0 1000 1000', 'highlightthickness': '0'})
        self.canvas = tk.Canvas(self,**{'height': '400', 'bg': '#4682b4', 'width': '400', 'scrollregion': (0, 0, 1000, 1000), 'highlightthickness': '0'})
Wenn tkinter die scrollregion so als string hat und sie nicht wieder so annimmt, das wäre ein tkinter Fehler. Bei mir hat tkinter das als tuple, nimmt aber auch den String mit Leerzeichen dazwischen an. Bei Dir nicht?

Das würde ich gerne wissen.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Alfons

Sorry! Du hast recht es funktioniert auch mit:

Code: Alles auswählen

self.canvas = tk.Canvas(self,**{'height': '400', 'bg': '#4682b4', 'width': '400', 'scrollregion': '0 0 1000 1000', 'highlightthickness': '0'})
Gruss wuf :wink:
Take it easy Mates!
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Hi wuf, der export ist eigentlich so gedacht, dass man den her nimmt und seinen code dazu macht

Code: Alles auswählen

import tkinter as tk
#import DynTkExtend as ext

class Application(tk.Tk):

    def __init__(self,**kwargs):
        tk.Tk.__init__(self,**kwargs)
        self.title('GuiDesigner supported design')
        self.main_frame = MainFrame(self)
        self.main_frame.pack(**{'fill': 'both', 'expand': 1})

class MainFrame(tk.Frame):

    def __init__(self,master,**kwargs):
        tk.Frame.__init__(self,master,**kwargs)
        self.bottom_frame = BottomFrame(self)
        self.top_frame = TopFrame(self)
        self.top_frame.pack(**{'fill': 'both'})
        self.bottom_frame.pack(**{'fill': 'x'})

        # code added here ===========================================
        canvas = self.top_frame.canvas
        yscrollbar = self.top_frame.yscrollbar
        xscrollbar = self.bottom_frame.xscrollbar

        canvas.config(xscrollcommand=xscrollbar.set,yscrollcommand=yscrollbar.set)
        xscrollbar.config(command=canvas.xview)
        yscrollbar.config(command=canvas.yview)

        canvas.create_line(0, 0, 1000, 1000, fill='yellow', width=2, arrowshape=(20,21,5),arrow='both')


class BottomFrame(tk.Frame):

    def __init__(self,master,**kwargs):
        tk.Frame.__init__(self,master,**kwargs)
        self.corner_frame = tk.Frame(self,**{'height': '11', 'width': '11'})
        self.xscrollbar = tk.Scrollbar(self,**{'elementborderwidth': '1', 'bd': '0', 'orient': 'horizontal'})
        self.xscrollbar.pack(**{'fill': 'x', 'side': 'left', 'expand': 1})
        self.corner_frame.pack(**{'fill': 'both', 'side': 'left'})

class TopFrame(tk.Frame):

    def __init__(self,master,**kwargs):
        tk.Frame.__init__(self,master,**kwargs)
        self.canvas = tk.Canvas(self,**{'height': '400', 'bg': '#4682b4', 'width': '400', 'scrollregion': '0 0 1000 1000', 'highlightthickness': '0'})
        self.yscrollbar = tk.Scrollbar(self,**{'elementborderwidth': '1', 'bd': '0'})
        self.canvas.pack(**{'side': 'left'})
        self.yscrollbar.pack(**{'fill': 'y', 'side': 'left'})

Application().mainloop()
Diese Variante wäre eine Schnellstartvariante aber nicht die eigentlich empfohlene Art und Weise. Dann gibt es noch zwei andere Arten, wovon die eine die ist, die man in diesem Forum möchte, aber zusätzlich mit XML-Format - das kommt schon noch - bitte Geduld - und werde mich auch um Kompatibilität mit pygubu bemühen, sofern bei Inkopatibilitäten Alejandro Autalán auch etwas tut, bzw. ich eine abgespeckte Variante generiere, die pygubu kompatibel ist.

Die dritte Variante gefällt besonders mir, aber da hat man in diesem Forum eine Menge dagegen.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

wuf hat geschrieben:Der tag [Codebox]Dein Code[/Codebox] scheint bei mir nicht zu funktionien. Vielleicht kannst du oder ein Moderator mir hierfür einen Tipp geben.
Huch, gerade habe ich schon was dazu geschrieben. Ist wohl nicht sonderlich intuitiv :roll:
Es muss [ Codebox=python file=Unbenannt.py][ /Codebox] heissen. Du kannst allerdings auch die Sprache in der Listbox ueber dem Textfeld heraussuchen und es wird eingefuegt.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Hi wuf, hier wäre die im Forum empfohlene Variante, die aber nicht die ist, die unbedingt meine uneingeschränkte Zustimmung teilt:

Code: Alles auswählen

import DynTkInter as tk

root = tk.Tk()

# don't do an import here, because in future it could be a XML-File
tk.load_script('scrollable_canvas_03.gui')

main_frame = tk.widget(root,'main_frame')
top_frame = tk.widget(main_frame,'top_frame')
bottom_frame = tk.widget(main_frame,'bottom_frame')

canvas = tk.widget(top_frame,'canvas')
yscrollbar = tk.widget(top_frame,'yscrollbar')
xscrollbar = tk.widget(bottom_frame,'xscrollbar')

canvas.config(xscrollcommand=xscrollbar.set,yscrollcommand=yscrollbar.set)
xscrollbar.config(command=canvas.xview)
yscrollbar.config(command=canvas.yview)
canvas.create_line(0, 0, 1000, 1000, fill='yellow', width=2, arrowshape=(20,21,5),arrow='both')

root.mainloop()
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Hi wuf, meine Philosophie ist etwas anders, als man hier im Forum gerne sähe.

Ich gehe davon aus:

Die GUI ist dynamisch, unvorhersehbar und hängt ganz davon ab, was der User tut. Und genausowenig, wie das ganze Internet in ein einziges Main Script passt, so läßt sich eine dynamische GUI in einem Main Script abhandeln. Zusätzlicher Code für die GUI sollte am Besten in den GUI Scripts selber enthalten sein. Aber hier ist man strikt dagegen.

Das sähe dann so aus. Hier das Main Script:

Code: Alles auswählen

import DynTkInter as tk
tk.Tk().mainloop('scroll.py')
Und hier das GUI Script scroll.py - mit zusätzlicher Code Sektion gegenüber Deinem Script scrollable_canvas_03.gui:

Code: Alles auswählen

config(**{'title': 'GuiDesigner supported design'})

Frame('main_frame')
goIn()

Frame('bottom_frame')
goIn()

Frame('corner_frame',**{'height': 11, 'width': 11})
Scrollbar('xscrollbar',**{'bd': '0', 'elementborderwidth': '1', 'orient': 'horizontal'})

widget('xscrollbar').pack(**{'side': 'left', 'expand': '1', 'fill': 'x'})
widget('corner_frame').pack(**{'side': 'left', 'fill': 'both'})

goOut()

Frame('top_frame')
goIn()

Canvas('canvas',**{'highlightthickness': '0', 'height': '400', 'scrollregion': ('0', '0', '1000', '1000'), 'width': '400', 'bg': '#4682b4'})
Scrollbar('yscrollbar',**{'bd': '0', 'elementborderwidth': '1'})

widget('canvas').pack(**{'side': 'left'})
widget('yscrollbar').pack(**{'side': 'left', 'fill': 'y'})

goOut()

widget('top_frame').pack(**{'fill': 'both'})
widget('bottom_frame').pack(**{'fill': 'x'})

### CODE ===================================================

canvas = widget('.','top_frame','canvas')
yscrollbar = widget('.','top_frame','yscrollbar')
xscrollbar = widget('.','bottom_frame','xscrollbar')

canvas.config(xscrollcommand=xscrollbar.set,yscrollcommand=yscrollbar.set)
xscrollbar.config(command=canvas.xview)
yscrollbar.config(command=canvas.yview)
canvas.create_line(0, 0, 1000, 1000, fill='yellow', width=2, arrowshape=(20,21,5),arrow='both')

### ========================================================

goOut()

widget('main_frame').pack(**{'expand': '1', 'fill': 'both'})
Ach so, funktioniert auch im GUI Designer, sofern Du es mit 'Load & Run' lädst.
Antworten