Abstand zwischen Widgets / Sprachenänderung

Fragen zu Tkinter.
GuardDog
User
Beiträge: 40
Registriert: Mittwoch 5. April 2017, 20:53
Wohnort: Hannover

Abstand zwischen Widgets / Sprachenänderung

Beitragvon GuardDog » Montag 25. Dezember 2017, 21:41

Hallo liebe Community,

erstmal wünsche ich euch (und eurer Familie) eine frohe und besinnliche Weihnachtszeit. Nun aber zu meinen 2 Fragen:

1. Ich möchte einen vertikalen Abstand zwischen meinen Widgets (Button) haben, Ich habe mich bereits im Internet schlaugemacht und die "pady"-Methode entdeckt. Komischer Weise fügt diese ein Abstand innerhalb des Buttons hinzu. Als Layoutmanager nutze ich "grid".

2. Möchte ich einen Weg haben, um die Sprache meiner Applikation umzuschalten. Dies möchte ich mit zwei Buttons mit Länderflaggen umsetzten. Wie ich die Bilder hinzufüge ist mir klar, aber gibt es eine Möglichkeit, um die Applikation praktisch neu zu laden,, allerdings mit anderssprachigen Buttons sobald man den dazugehörigen Knopf gedrückt hat? Ich würde es mit der ".destroy()"-Methode versuchen, aber die Umsetzung ist mir etwas schleierhaft.

Ich benutze Python in der Version 3.6. Hier mein Code:

Code: Alles auswählen

from tkinter import *
import os

root = Tk()
root.title("Republic at War 1.2")

def install():
   os.system('start "" "data\installer\Republic at War 1.2.exe"')

def uninstall():
   os.system('start "" "data\installer\RaW Uninstaller.exe"')

def launcher():
   print("test")

def depatch():
   print("test")

def manual():
   os.system('"start "" "data\nmanual.pdf"')

install_btn = Button(root, text="Install", command=install, relief="solid", borderwidth=1, pady=1, width=45)
uninstall_btn = Button(root, text="Uninstall", command=uninstall, relief="solid", borderwidth=1, pady=1, width=45)
launcher_btn = Button(root, text="Apply launcher", command=launcher, relief="solid", borderwidth=1, pady=1, width=45)
depatch_btn = Button(root, text="Install the german patch", command=depatch, relief="solid", borderwidth=1, pady=1, width=45)
manual_btn = Button(root, text="Read the manual", command=manual, relief="solid", borderwidth=1, pady=1, width=45)

install_btn.grid(row=1, column=1)
uninstall_btn.grid(row=2, column=1)
launcher_btn.grid(row=3, column=1)
depatch_btn.grid(row=4, column=1)
manual_btn.grid(row=5, column=1)

root.mainloop()
Benutzeravatar
noisefloor
User
Beiträge: 2226
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: Görgeshausen
Kontaktdaten:

Re: Abstand zwischen Widgets / Sprachenänderung

Beitragvon noisefloor » Montag 25. Dezember 2017, 22:13

Hallo,

du solltest deine Code mal dringend in eine Klasse packen, dass ist sauberer, übersichtlicher, besser wartbar.

Zum Abstand: IMHO musst du den Abstand dem `install_btn.grid(row=1, column=1)` mitgeben, also z.B. `install_btn.grid(row=1, column=1, pady=15)`, siehe auch: http://effbot.org/tkinterbook/grid.htm

Zur Sprache: von Prinzip sollte das so gehen, dass du ein Event an den Button bindest, dass bei einem Klcik darauf alle Labels / Text / Beschriftungen / ... ändert.

`os.system` ist veraltet, das steht auch wörtlich in der Python-Doku. Besser ist, das `subprocess` Modul zu nutzen.

Sternchenimporte sind schlecht, weil du dir dann alles mögliche in einen Namensraum holst - was zu unerwünschten und schwer nachzuvollziehenden Nebeneffekten führen kann.

Gruß, noisefloor
GuardDog
User
Beiträge: 40
Registriert: Mittwoch 5. April 2017, 20:53
Wohnort: Hannover

Re: Abstand zwischen Widgets / Sprachenänderung

Beitragvon GuardDog » Montag 25. Dezember 2017, 22:20

Hi,

erstmal ein großes DANKE :) für deine schnelle Antwort. Leider habe ich das Nutzen von *-importen und das "klassenlose Programmieren" so gelernt und bin mit den anderen Methoden nie so richtig warm geworden. Aber da jetzt ja Ferien sind, hab' ich ja genug Zeit!
suk
User
Beiträge: 17
Registriert: Sonntag 17. Dezember 2017, 01:18

Re: Abstand zwischen Widgets / Sprachenänderung

Beitragvon suk » Montag 25. Dezember 2017, 23:09

Ein Ansatz wäre, Deine Applikation erstmal ohne Beschriftungen mit leeren Platzhaltern aufzubauen.
Dann könntest Du Dir zusätzlich eine Funktion "Beschriftung" schreiben, welche Dir per config alle Beschriftungen aus einer Liste zieht und setzt. Die Liste ließe sich ja z.B. auch als ini-Datei o.ä. speichern und von extern warten.
Die Liste lädst Du dann je nach Sprachauswahl länderspezifisch und rufst noch "Beschriftung" auf.
So würdest Du Dir die Rechenleistung für das Destroy und Neubauen aller Grafikelemente sparen.

Hinweis: Bin selber noch kräftig am lesen und lernen und kann somit leider noch kein konkretes Beispiel bringen. Das wäre jedoch mein theoretischer Ansatz, um flexible Beschriftungen leicht nachpflegbar zu realisieren.
Benutzeravatar
wuf
User
Beiträge: 1366
Registriert: Sonntag 8. Juni 2003, 09:50

Re: Abstand zwischen Widgets / Sprachenänderung

Beitragvon wuf » Dienstag 26. Dezember 2017, 01:25

Hi GuardDog

Hier dein Skript als Klasse und den angepassten vertikal- & horizontal Abständen:
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. import os
  5. from functools import partial
  6.  
  7. try:
  8.     # Tkinter for Python 2.xx
  9.     import Tkinter as tk
  10. except ImportError:
  11.     # Tkinter for Python 3.xx
  12.     import tkinter as tk
  13.  
  14. APP_TITLE = "Republic at War 1.2"
  15. APP_XPOS = 100
  16. APP_YPOS = 100
  17. APP_WIDTH = 300
  18. APP_HEIGHT = 200
  19.  
  20. BUTTONS = [
  21.     "Install",
  22.     "Uninstall",
  23.     "Apply launcher",
  24.     "Install the german patch",
  25.     "Read the manual"
  26.     ]
  27.  
  28. SUBPROCESSES = [
  29.     ['os', 'start "" "data\installer\Republic at War 1.2.exe"'],
  30.     ['os', 'start "" "data\installer\RaW Uninstaller.exe"'],
  31.     ['launcher', "test"],
  32.     ['dispatch', "test"],
  33.     ['os', '"start "" "data\nmanual.pdf"']
  34.     ]
  35.  
  36.    
  37. class Application(tk.Frame):
  38.  
  39.     def __init__(self, master):
  40.         self.master = master
  41.         tk.Frame.__init__(self, master)
  42.        
  43.         for row, button_name in enumerate(BUTTONS):
  44.             tk.Button(self, text=button_name, relief='solid', bd=1, width=45,
  45.                 command=partial(self.button_callback, row)
  46.                 ). grid(row=row, column=0, padx=2, pady=2)
  47.                
  48.     def button_callback(self, row):
  49.         function, text = SUBPROCESSES[row]
  50.  
  51.         if function == 'os':
  52.             os.system(text)
  53.             # evt. Durch 'subprocess' ersetzen
  54.            
  55.         if function == 'launcher':
  56.             print(text)
  57.            
  58.         if function == 'dispatch':
  59.             print(text)
  60.        
  61. def main():
  62.     app_win = tk.Tk()
  63.     app_win.title(APP_TITLE)
  64.     app_win.geometry("+{}+{}".format(APP_XPOS, APP_YPOS))
  65.     #app_win.geometry("{}x{}".format(APP_WIDTH, APP_HEIGHT))
  66.    
  67.     app = Application(app_win).pack(fill='both', expand=True)
  68.    
  69.     app_win.mainloop()
  70.  
  71.  
  72. if __name__ == '__main__':
  73.     main()      
Gruss wuf :wink:
Take it easy Mates!
Benutzeravatar
noisefloor
User
Beiträge: 2226
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: Görgeshausen
Kontaktdaten:

Re: Abstand zwischen Widgets / Sprachenänderung

Beitragvon noisefloor » Dienstag 26. Dezember 2017, 08:48

Hallo,

@wuf: in SUBPROCESSES musst du die Backslashs mit eine Backslash escapen - so funktioniert das nicht. `\n` ist sonst ein Linebreak. Außerdem benutzt du auch immer noch `os.system` statt `subprocess`.

Gruß, noisefloor
Sirius3
User
Beiträge: 7043
Registriert: Sonntag 21. Oktober 2012, 17:20

Re: Abstand zwischen Widgets / Sprachenänderung

Beitragvon Sirius3 » Dienstag 26. Dezember 2017, 09:48

@wuf: statt zwei Listen, in denen die Information parallel gespeichert wird, solltest Du nur eine gemeinsame verwenden. Wenn man mehrere sich ausschließende if hat, dann benutzt man elif.

  1. from functools import partial
  2. import tkinter as tk
  3. from subprocess import call
  4.  
  5. ACTIONS = [
  6.     ("Install", "start", r"data\installer\Republic at War 1.2.exe"),
  7.     ("Uninstall", "start", r"data\installer\RaW Uninstaller.exe"),
  8.     ("Apply launcher", "launch", "test"),
  9.     ("Install the german patch", "dispatch", "test"),
  10.     ("Read the manual", "start", r"data\nmanual.pdf"),
  11. ]
  12.    
  13. class Application(tk.Tk):
  14.     def __init__(self):
  15.         tk.Tk.__init__(self)
  16.         self.title("Republic at War 1.2")
  17.        
  18.         for row, (title, command, argument) in enumerate(ACTIONS):
  19.             tk.Button(self, text=title, relief='solid', bd=1, width=45,
  20.                 command=partial(self.button_callback, row)
  21.                 ). grid(row=row, column=0, padx=2, pady=2)
  22.                
  23.     def button_callback(self, command. argument):
  24.         if command == 'start':
  25.             call(["start", "", argument])
  26.         elif command == 'launcher':
  27.             print(text)
  28.         elif command == 'dispatch':
  29.             print(text)
  30.        
  31. def main():
  32.     app = Application()
  33.     app.mainloop()
  34.  
  35. if __name__ == '__main__':
  36.     main()
GuardDog
User
Beiträge: 40
Registriert: Mittwoch 5. April 2017, 20:53
Wohnort: Hannover

Re: Abstand zwischen Widgets / Sprachenänderung

Beitragvon GuardDog » Dienstag 26. Dezember 2017, 23:25

Hey,

eine Frage hätte ich da noch. Wie kann man eine Datei kopieren? Ich würde hier wieder os.system nehmen. Der Zielordner soll eine Variable sein. Geht das irgendwie?
Sirius3
User
Beiträge: 7043
Registriert: Sonntag 21. Oktober 2012, 17:20

Re: Abstand zwischen Widgets / Sprachenänderung

Beitragvon Sirius3 » Dienstag 26. Dezember 2017, 23:46

@GuardDog: dafür gibt es shutil.copyfile
Benutzeravatar
wuf
User
Beiträge: 1366
Registriert: Sonntag 8. Juni 2003, 09:50

Re: Abstand zwischen Widgets / Sprachenänderung

Beitragvon wuf » Sonntag 31. Dezember 2017, 12:12

noisefloor hat geschrieben:@wuf: in SUBPROCESSES musst du die Backslashs mit eine Backslash escapen - so funktioniert das nicht. `\n` ist sonst ein Linebreak. Außerdem benutzt du auch immer noch `os.system` statt `subprocess`.

Danke für deinen Hinweis. Habe das linear geschriebene Skript des OP's in eine Klasse umgewandelt. Die von dir erwähnten Textzeilen, welche mich nicht weiter interessierten habe ich mit Copy & Paste vom Beitrag übernommen und in eine Liste eingefügt. Wollte dessen Korrektur dem OP überlassen.

Gruss wuf :wink:
Take it easy Mates!
Benutzeravatar
wuf
User
Beiträge: 1366
Registriert: Sonntag 8. Juni 2003, 09:50

Re: Abstand zwischen Widgets / Sprachenänderung

Beitragvon wuf » Sonntag 31. Dezember 2017, 12:18

Sirius3 hat geschrieben:@wuf: statt zwei Listen, in denen die Information parallel gespeichert wird, solltest Du nur eine gemeinsame verwenden. Wenn man mehrere sich ausschließende if hat, dann benutzt man elif.

Danke Sirius3 für deine lehrreichen Hinweise und die sukksessive Verfeinerung des Skripts. Bei deinem Skript hat sich noch ein kleines Fehlerchen eingeschlichen:

Code: Alles auswählen

def button_callback(self, command. argument)
korrigiert:

Code: Alles auswählen

def button_callback(self, command, argument)

Gruss wuf :wink:
Take it easy Mates!

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder