Botton innerhalb Frame

Fragen zu Tkinter.
Antworten
jake-the-snake

Hallo Leute

Bei diesem Code hier:

Code: Alles auswählen

# Einleitung der App-Knoepfe
class App:
  # Sprungmarke?
  def __init__(self, master):
    frame = Frame(master)
    frame.place(x=300,y=60)
    
    # Erstellt den Knopf Quit?
    self.button = Button(frame, 
                         text="QUIT", fg="red",
                         command=frame.quit)
    self.button.pack()
    
    # Erstellt den Knopf Hello?
    self.slogan = Button(frame,
                         text="Hello",
                         command=self.write_slogan)
    self.slogan.pack()
  
# Sprungmarke?
  def write_slogan(self):
    print ("Tkinter is easy to use!")

root = Tk()

# Keine Ahnung was das hier drunter ist?
app = App(root)
...habe ich mal bei Remark mit Fragezeichen hingeschrieben, was ich glaube zu wissen was dort passiert. :?

Mein Hauptproblem beschreibt sich so:

Ich kann zwar die Position der beiden Knöpfe in Zeile 6 nach belieben ändern, aber innerhalb des frames kann ich die Einzelknöpfe nicht verschieben.
Die zwei knöpfe kleben aneinander - ich will sie mit Zwischenraum über und unter dem Knopf - also zwei getrennte Knöpfe.

Wenn ich in Zeile 12 und 18 das pack() durch place(x=123,y=456) ändere, verschwindet der Knopf.
Wie bekomme ich die Knöpfe auseinander?

Gruß jts
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na du hast dich ja gruendlich entschieden meine Hinweise alle zu ignorieren. Darum hier noch ein paar weitere zum links liegen lassen:

Es hat wenig Sinn, place mit pack/grid zu mischen. Entweder du weisst besser, was wohin gehoert. Oder du ueberlaesst das dem Layout Management. Mach also aus deinem place ein pack, und pack sie wohin du willst.

Und da du ja besser weisst wohin die Widgets sollen, liefert das System dir auch keine Hilfestellung in Form von automatischer Berechnung der Dimension deines Frames. Stattdessen musst du dem place auch width und height mitgeben. Wenn du das nicht machst, ist es 1x1 Pixel gross, und die Kinder sind unsichtbar.

Last but not least: deine Kommentare zeugen von einem recht fundamentalen Missverstaendnis was Funktionen bzw. Methoden und der Konstruktor sind. Sprungmarken gibt es nicht in Python. Dazu empfiehlt sich das durcharbeiten eines Tutorials zB auf python.org
jake-the-snake

Hi deets
Na du hast dich ja gruendlich entschieden meine Hinweise alle zu ignorieren
Wenn du damit kivy meinst - ja. Es wird bei der Dokumentation vom Raspberry ausdrücklich empfohlen, für eigene Programme im Idealfall Python und im Netz dazu tkinter zu verwenden. Was in vielen Youtube-Tutorials ja auch bestätigt wird.

Und zum place(): Ich hatte doch geschrieben, dass das Programm auf genau einem Device, mit einem bekannten Display, unter einer einzigen Werkseinstellung, mit nur diesem Programm, nur für einen einzigen Zweck geschrieben wird. Quasi als HMI-Gerät. Es wird da keine Änderungen vom User geben. Also wenn man in diesem Fall kein place() nehmen kann, dann weiss ich auch nicht, in welchem Fall du dann place() verwenden willst.
deine Kommentare zeugen von einem recht fundamentalen Missverstaendnis was Funktionen bzw. Methoden und der Konstruktor sind. Sprungmarken gibt es nicht in Python
In Perl enden Sprungmarken mit einem Doppelpunkt. Ich dachte es ist eventuell ähnlich wie Perl. Dann habe ich halt etwas falsches angenommen - Ja schuldig im Sinne der Anklage...

Das man nur eine Platzierungsart verwenden darf, weiss ich. Die Knöpfe sind von einem Beispiel aus dem Internet. Und ich versuche jetzt lediglich diese anzupassen - sonst wäre ich ja nicht hier...
Und da du ja besser weisst wohin die Widgets sollen, liefert das System dir auch keine Hilfestellung in Form von automatischer Berechnung der Dimension deines Frames. Stattdessen musst du dem place auch width und height mitgeben. Wenn du das nicht machst, ist es 1x1 Pixel gross, und die Kinder sind unsichtbar.
Vielen Dank dafür. Das war eine brauchbare Info, die einem Python -Anfänger wie mir weiterhilft. Da nehm ich doch auch gerne den mitschwingenden Sarkasmus in Kauf :wink:

Gruß jts
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

jake-the-snake hat geschrieben:
Na du hast dich ja gruendlich entschieden meine Hinweise alle zu ignorieren
Wenn du damit kivy meinst - ja. Es wird bei der Dokumentation vom Raspberry ausdrücklich empfohlen, für eigene Programme im Idealfall Python und im Netz dazu tkinter zu verwenden. Was in vielen Youtube-Tutorials ja auch bestätigt wird.
Das ist so Unsinn. Kivy ist fuer mobile Geraete fuer Full-Screen Anwendungen gemacht. Es ist leider gerade im PI-Umfeld eine Menge Unfug in Umlauf. Code der wirklich grenzwertig schlecht ist, etc.

Am Ende ist das natuerlich deine Entscheidung, aber deutlich bessere Interaktion, moderner die auch wirklich auf Touch eingestellt ist bekommst du halt nur mit Kivy. Zb ein bisschen hier zu sehen: https://www.youtube.com/watch?v=Eah3Zq18OyM

Und falls es da ein Missverstaendnis gibt: Kivy basiert auf Python.
jake-the-snake hat geschrieben: Und zum place(): Ich hatte doch geschrieben, dass das Programm auf genau einem Device, mit einem bekannten Display, unter einer einzigen Werkseinstellung, mit nur diesem Programm, nur für einen einzigen Zweck geschrieben wird. Quasi als HMI-Gerät. Es wird da keine Änderungen vom User geben. Also wenn man in diesem Fall kein place() nehmen kann, dann weiss ich auch nicht, in welchem Fall du dann place() verwenden willst.
Und darauf hatte ich ebenfalls geantwortet: ich wuerde es trotzdem machen. Place ist eine veraltete Methode, Widget-Layout zu betreiben. Du magst keine nutzerseitigen Einfluesse haben, aber in dem Moment wo auch schon beim Entwurf nach 50 muehselig plazierten Widgets dein Chef sagt "schick, aber jetzt bitte alles mit Comic Sans!" raufst du dir die Haare. place und grid sind da dann viel genuegsamer. Klar, zaubern koennen die auch nicht, wenn die Widgets nicht mehr auf den Bildschirm passen, ist essig. Aber es ist deutlich angenehmer damit zu arbeiten.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi jake-the-snake

Wie soll den die Anordnung der Buttons aussehen? Hier ein Beispiel mit einem Button links oben und der andere rechts unten mit dem Pack Layouter erstellt:

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
except ImportError:
    # Tkinter for Python 3.xx
    import tkinter as tk

APP_TITLE = "Button Placing"
APP_XPOS = 100
APP_YPOS = 100
APP_WIDTH = 300
APP_HEIGHT = 200


class Application(tk.Frame):

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

        # Erstellt den Knopf Hello?
        self.slogan = tk.Button(self,
                             text="Hello",
                             command=self.write_slogan)
        self.slogan.pack(side='left', anchor='n')

        # Erstellt den Knopf Quit?
        self.button = tk.Button(self,
                             text="QUIT", fg="red",
                             command=master.quit)
        self.button.pack(side='right', anchor='s')
       
 
    def write_slogan(self):
        print ("Tkinter is easy to use!")
          
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(fill='both', expand=True)
    
    app_win.mainloop()
 
 
if __name__ == '__main__':
    main()      
Gruss wuf :wink:
Take it easy Mates!
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

@wuf ich glaube du hast einen kleinen Fehler. Der Rückgabewert von pack ist None. Konsequenterweise damit auch app.
jake-the-snake

Hallo zusammen

@deets
Erst mal Dank für das verlinkte Video. Im FullScreen sieht das natürlich auch nicht schlecht aus - das muss man sagen. Touch-Screen-Funktionalität zu haben wäre ein schöner Luxus. Man könnte auf die Maus verzichten. Anwendungsbedingt wird aber eh eine Tastatur dabei sein. Gibt es denn bei tkinter und Python keine Möglichkeit, Touchfunktionen ab zu fragen?
Weisst du, ich habe mit so vielen Leuten gesprochen, und alle waren der Meinung, dass ein späteres Kompilieren von Ubuntu 16.04 auf Raspi-Bedürfnisse über Python und tk am einfachsten wäre.

@wuf
Mein System meldet Fehler in Zeile 4 (Unter Perl würd ich jetzt sagen mir fehlt eventuell das Modul functools):

[codebox=bash file=Unbenannt.bsh] File "Neu.py", line 4
from functools import partial
^
IndentationError: unexpected indent
[/code]

Schade, ich hätte das gern mal gesehen.

Die vier Knöpfe sind jetzt halt mal untereinander. Sieht nicht mal so schlecht aus. Eventuell finde ich noch eine Möglichkeit, in Richtung Padding - bzw. padx und pady heisst das ja hier :)

Gruß jts

P.S. Alles gut 8)
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Multitouch in tk geht nicht. Und die Portierung von Ubuntu halte ich auch nicht für problematisch, Kivy kann auch größer.

Wie dem auch sei: der Fehler ist irgendwie durch copy & paste entstanden. Einrückung ist wichtig in Python.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

__deets__ hat geschrieben:@wuf ich glaube du hast einen kleinen Fehler. Der Rückgabewert von pack ist None. Konsequenterweise damit auch app.
Stimmt. Nun ist er behoben:

Code: Alles auswählen

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

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

APP_TITLE = "Button Placing"
APP_XPOS = 100
APP_YPOS = 100
APP_WIDTH = 300
APP_HEIGHT = 200


class Application(tk.Frame):

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

        # Erstellt den Knopf Hello?
        self.slogan = tk.Button(self,
                             text="Hello",
                             command=self.write_slogan)
        self.slogan.pack(side='left', anchor='n')

        # Erstellt den Knopf Quit?
        self.button = tk.Button(self,
                             text="QUIT", fg="red",
                             command=master.quit)
        self.button.pack(side='right', anchor='s')
       
 
    def write_slogan(self):
        print ("Tkinter is easy to use!")
          
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)
    app.pack(fill='both', expand=True)
    
    print(app)
    
    app_win.mainloop()
 
 
if __name__ == '__main__':
    main()      
jake-the-snake hat geschrieben:@wuf
Mein System meldet Fehler in Zeile 4 (Unter Perl würd ich jetzt sagen mir fehlt eventuell das Modul functools):

Code: [Alles auswählen] [Erweitern/Minimieren]

File "Neu.py", line 4
from functools import partial
^
IndentationError: unexpected indent

GeSHi © Codebox Plus Extension


Schade, ich hätte das gern mal gesehen.
Das Modul:
from functools import partial
braucht es nicht. Geht also auch ohne. Deine Zeile hat einen Einrückungsfehler.

Gruss wuf :wink:
Take it easy Mates!
jake-the-snake

Hallo zusammen

Jetzt hat es geklappt.
Danke an Alle :D

Gruß jts
Antworten