ZOOM für tkinter-GUI bei verschiedenen Displaygrößen?

Fragen zu Tkinter.
Nobuddy
User
Beiträge: 996
Registriert: Montag 30. Januar 2012, 16:38

Das heißt dann, wenn der Wert irgendwo weiter oben schon verwendet wurde, ist er weiter unten nicht mehr da.

PS: Das mit copy.copy(wert), auch auch nur funktioniert, weil ich einen anderen Namen dafür vergeben habe, als weiter oben. :?

Wie kann ich das lösen, wenn der Wert mehrmals in der GUI benötigt wird?

Nachtrag:
Ob es die Lösung jetzt ist, weiß ich nicht.
Wenn ich mir das Layout so hole

Code: Alles auswählen

        self.mylayout = ScreenConf(self.screenx, self.screeny).myscreen()
und dann über jede Zeile, die einer der Werte aus self.mylayout benötigt, dies z.B. einfüge:

Code: Alles auswählen

        self.txt2 = copy.copy(self.mylayout[1])
dann funktioniert es.

Gibt es da evtl. noch eine bessere Lösung?
Nobuddy
User
Beiträge: 996
Registriert: Montag 30. Januar 2012, 16:38

@BlackJack, jetzt habe ich verstanden, was Du mir mit Deinem letzten Post, sagen wolltest.

Ich habe tatsächlich den Namen 'self.txt' und 'self.txt2' bei Labels vergeben, klar das nicht funktionieren kann .... :oops:
Nach dem ich das behoben habe, funktioniert es ohne Klimmzüge ... :wink:

Grüße Nobuddy
Nobuddy
User
Beiträge: 996
Registriert: Montag 30. Januar 2012, 16:38

@BlackJack, habe das Ganze optimiert und dürfte etwa dem entsprechen, was Du am Anfang mit auslagern usw. geschrieben hast.

Meine gui_screendefinition.txt, beinhaltet die Displaygröße mit Größenwerten (TAB-getrennt).
1600 x 900 10 11 7 28 25 16 12 14 49
1680 x 1050 12 14 8 34 30 20 15 17 60
Meine gui_screenconf.py, gibt das entsprechende Displaylayout aus, bzw. wenn das Displaylayout in gui_screendefinition.txt nicht vorhanden ist, wird das neue Displaylayout berechnet und in die gui_screendefinition.txt hinzugefügt und anschließend gleich ausgegeben.
Für die Berechnung des neuen Layouts, verwende ich als Basis 1680 x 1050 und setzte ein Verhältnis dazu.
Das neue Displaylayout, kann dann nach eigenen Wünschen verändert werden.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# For Python3.x


import os
import csv
import codecs
from functools import partial

"""Private Module"""
import data_load as Data


## Schreiben Daten in Datei
# Schreibe die Daten von datenpool in filename
def write_csv(filename, datenpool):
    with codecs.open(filename, "w") as zielfile:
        writer = csv.writer(zielfile, delimiter="\t", quotechar="^")
        writer.writerows(datenpool)

my_reader = partial(csv.reader, delimiter='\t', quotechar='^')

class ScreenConf(object):
    """
    Gebe für die Displaygröße, das entsprechende Layout aus.
    Rüchgabewert:
    - Text normal, für Textausgabe
    - Text ca. 16 % größer als normal, für Buttons und Texteingabe
    - wie oben, Schrift fett
    - Höhe von unterem Frame
    - Breite Distanz
    - Breite Distanz2
    - Breite Distanz3
    - Breite Distanz4
    - Breite Eingabe Textfeld
    - Breite Eingabe2 Textfeld
    - Schriftfarbe schwarz
    - Schriftfarbe weiß
    - Schriftfarbe dunkelgrau, Buttons
    - Schriftfarbe dunkelrot, Buttons
    - Hintergrundfarbe grau, für Texteingabe, Textfenster, Buttons
    """

    def __init__(self, screenx, screeny):

        self.screenx = screenx
        self.screeny = screeny
        self.base_xy = 1680, 1050
        self.font = 'NimbusSansL'   # Schriftart
        self.col1 = 'black'
        self.col2 = 'white'
        self.col3 = 'darkgrey'
        self.col4 = 'darkred'
        self.col5 = 'grey'

        self.filelist = 'screendefinition'
        self.screen = Data.ListDef(self.filelist, 'screen')
        with codecs.open(Data.Path(self.filelist), 'r') as infile:
            for row in my_reader(infile):
                if row[self.screen] == '{} x {}'.format(self.screenx,
                        self.screeny):
                    self.screenline = row


    def myscreen(self):
        """
        Berechne die neue Displaygröße anhand der Basiswerte.
        Erstelle Datensatz für neues Display in 'gui_screendefinition'.
        """

        try:
            self.mylist = list()
            for i, row in enumerate(self.screenline):
                if i != 0 and i < 3:
                    self.mylist.append((self.font, row))
                if i == 2:
                    self.mylist.append((self.font, row, 'bold'))
                if i > 2:
                    self.mylist.append(row)
            self.mylist.append(self.col1)
            self.mylist.append(self.col2)
            self.mylist.append(self.col3)
            self.mylist.append(self.col4)
            self.mylist.append(self.col5)
            return self.mylist
        except AttributeError:
            self.x_diff = round((self.screenx / self.base_xy[0]), 2)
            self.y_diff = round((self.screeny / self.base_xy[1]), 2)
            self.diff = self.x_diff * self.y_diff
            data = list()
            with codecs.open(Data.Path(self.filelist), 'r') as infile:
                for row in my_reader(infile):
                    if row[self.screen] == '{} x {}'.format(self.base_xy[0],
                        self.base_xy[1]):
                        self.baseline = row
                    data.append(row)
            mynewlist = list()
            for i, row in enumerate(self.baseline):
                if i == 0:
                    mynewlist.append('{} x {}'.format(self.screenx,
                        self.screeny))
                else:
                    mynewlist.append(round(float(row) * self.diff))
            newdata = list()
            newdata.append(mynewlist)
            [newdata.append(row) for row in data]
            write_csv(Data.Path(self.filelist), sorted(newdata))
            mylist = list()
            for i, row in enumerate(self.mynewlist):
                if i != 0 and i < 3:
                    self.mylist.append((self.font, row))
                if i == 2:
                    self.mylist.append((self.font, row, 'bold'))
                if i > 2:
                    self.mylist.append(row)
            self.mylist.append(self.col1)
            self.mylist.append(self.col2)
            self.mylist.append(self.col3)
            self.mylist.append(self.col4)
            self.mylist.append(self.col5)
            return mylist


if __name__ == '__main__':
    # Test
    ScreenConf(1600, 900).myscreen()
Um eine Gui mit den Werten zu steuern, habe ich folgenden Eintrag in der GUI.

Code: Alles auswählen

"""Private Module"""
from gui_screenconf import ScreenConf

class View(object):

    def __init__(self, controller):
        self.port = prog_check(PROGRAMMNAME)
        print('Port: %s, PID: %s' % (self.port, os.getpid()))
 
        self.root = tk.Tk()
        self.title = "EDV-Work"
        self.root.title(self.title)
        self.controller = controller
        xpos = 0
        ypos = 0
        self.screenx = self.root.winfo_screenwidth()
        self.screeny =  self.root.winfo_screenheight()
        self.root.geometry("%dx%d+%d+%d" % (self.screenx,
            self.screeny, xpos, ypos))

        # Layout Definition
        self.mylayout = ScreenConf(self.screenx, self.screeny).myscreen()
        self.txt = copy.copy(self.mylayout[0])
        self.txt2 = copy.copy(self.mylayout[1])
        self.txt2b = copy.copy(self.mylayout[2])
        self.fluy = copy.copy(self.mylayout[3])
        self.distanzx = copy.copy(self.mylayout[4])
        self.distanzx2 = copy.copy(self.mylayout[5])
        self.distanzx3 = copy.copy(self.mylayout[6])
        self.distanzx4 = copy.copy(self.mylayout[7])
        self.eingabex = copy.copy(self.mylayout[8])
        self.eingabex2 = copy.copy(self.mylayout[9])
        self.fc = copy.copy(self.mylayout[10])
        self.fcw = copy.copy(self.mylayout[11])
        self.fcdg = copy.copy(self.mylayout[12])
        self.fcdr = copy.copy(self.mylayout[13])
        self.bg = copy.copy(self.mylayout[14])
Funktionieren tut es, auch mit neuen Displaygrößen.
Hoffe, daß nicht all zuviele Fehler drin sind ... :wink:

Grüße Nobuddy
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Warum verwendest Du kein beschreibenderes Dateiformat, wie z.B. JSON?
Die ganze Konstruktion mit »AttributeError« verstehe ich nicht. Zudem hast Du noch fehlerhafte Zuweisungen. Mal benutzt Du »self.mylist« und mal nur »mylist«. Dabei sind sowohl der Name als auch die Konstruktion an sich schwer zu durchschauen und fehleranfällig. Weist Du überhaupt, was Du mit »copy.copy« kopierst? (Kleiner Tipp: gar nichts, weil bei nicht veränderbaren Datentypen die übergebene Referenz zurückgegeben wird)
Nobuddy
User
Beiträge: 996
Registriert: Montag 30. Januar 2012, 16:38

Hallo Sirius3
Sirius3 hat geschrieben:Warum verwendest Du kein beschreibenderes Dateiformat, wie z.B. JSON?
JSON, habe ich schon mal gehört, wußte aber nicht, daß es ein Dateiformat ist.
Was ist da so besonderes dran?
Sirius3 hat geschrieben:Die ganze Konstruktion mit »AttributeError« verstehe ich nicht.
In der <__init__> vergleiche ich die mit 'screenx, screeny' übergebene Displaygröße in meiner 'gui_screendefinition.txt', ob diese vorhanden ist. Wenn ja, so wird dies an 'self.screenline' übergeben. Ist diese Displaygröße noch nicht vorhanden, so erfolgt in der Funktion 'myscreen' eben der »AttributeError«, womit es dann dort unter 'except AttributeError' weitergeht.
Sirius3 hat geschrieben:Zudem hast Du noch fehlerhafte Zuweisungen. Mal benutzt Du »self.mylist« und mal nur »mylist«. Dabei sind sowohl der Name als auch die Konstruktion an sich schwer zu durchschauen und fehleranfällig.
Da werde ich nochmals drüber schauen und es korrigieren.
Sirius3 hat geschrieben:Weist Du überhaupt, was Du mit »copy.copy« kopierst? (Kleiner Tipp: gar nichts, weil bei nicht veränderbaren Datentypen die übergebene Referenz zurückgegeben wird)
Ok, dann ist das mit »copy.copy« überflüssig, werde das korrigieren.

Grüße Nobuddy
Nobuddy
User
Beiträge: 996
Registriert: Montag 30. Januar 2012, 16:38

Ich habe das mit Sirius3ś Kritik, verbessert und unnötige Einträge vereinfacht.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# For Python3.x


import os
import csv
import codecs
from functools import partial

"""Private Module"""
import data_load as Data


## Schreiben Daten in Datei
# Schreibe die Daten von datenpool in filename
def write_csv(filename, datenpool):
    with codecs.open(filename, "w") as zielfile:
        writer = csv.writer(zielfile, delimiter="\t", quotechar="^")
        writer.writerows(datenpool)

my_reader = partial(csv.reader, delimiter='\t', quotechar='^')

class ScreenConf(object):
    """
    Gebe für die Displaygröße, das entsprechende Layout aus.
    Rüchgabewert:
    - Text normal, für Textausgabe
    - Text ca. 16 % größer als normal, für Buttons und Texteingabe
    - wie oben, Schrift fett
    - Höhe von unterem Frame
    - Breite Distanz
    - Breite Distanz2
    - Breite Distanz3
    - Breite Distanz4
    - Breite Eingabe Textfeld
    - Breite Eingabe2 Textfeld
    - Schriftfarbe schwarz
    - Schriftfarbe weiß
    - Schriftfarbe dunkelgrau, Buttons
    - Schriftfarbe dunkelrot, Buttons
    - Hintergrundfarbe grau, für Texteingabe, Textfenster, Buttons
    """

    def __init__(self, screenx, screeny):

        self.screenx = screenx
        self.screeny = screeny
        self.base_xy = 1680, 1050
        self.font = 'NimbusSansL'   # Schriftart
        self.col1 = 'black'
        self.col2 = 'white'
        self.col3 = 'darkgrey'
        self.col4 = 'darkred'
        self.col5 = 'grey'

        self.filelist = 'screendefinition'
        self.screen = Data.ListDef(self.filelist, 'screen')
        with codecs.open(Data.Path(self.filelist), 'r') as infile:
            for row in my_reader(infile):
                if row[self.screen] == '{} x {}'.format(self.screenx,
                        self.screeny):
                    self.screenline = row


    def myscreen(self):
        """
        Berechne die neue Displaygröße anhand der Basiswerte.
        Erstelle Datensatz für neues Display in 'gui_screendefinition'.
        """

        mylist = list()
        try:
            # Erstelle das Displaylayout.
            for i, row in enumerate(self.screenline):
                if i != 0 and i < 3:
                    mylist.append((self.font, row))
                if i == 2:
                    mylist.append((self.font, row, 'bold'))
                if i > 2:
                    mylist.append(row)
        except AttributeError:
            # Verhältnis zwischen der Basis-Displaygröße
            # und der neuen Displaygröße definieren.
            self.x_diff = round((self.screenx / self.base_xy[0]), 2)
            self.y_diff = round((self.screeny / self.base_xy[1]), 2)
            self.diff = self.x_diff * self.y_diff
            # Lade die Werte der Basis-Displaygröße
            # Erstelle Liste aus self.filelist
            data = list()
            with codecs.open(Data.Path(self.filelist), 'r') as infile:
                for row in my_reader(infile):
                    if row[self.screen] == '{} x {}'.format(self.base_xy[0],
                            self.base_xy[1]):
                        self.baseline = row
                    data.append(row)
            # Erstelle die Werte für die neue Displaygröße
            mynewlist = list()
            for i, row in enumerate(self.baseline):
                if i == 0:
                    mynewlist.append('{} x {}'.format(self.screenx,
                        self.screeny))
                else:
                    mynewlist.append(round(float(row) * self.diff))
            # Aktualisiere self.filelist mit den neuen Werten.
            newdata = list()
            newdata.append(mynewlist)
            [newdata.append(row) for row in data]
            write_csv(Data.Path(self.filelist), sorted(newdata))
            # Erstelle das neue Displaylayout.
            for i, row in enumerate(self.mynewlist):
                if i != 0 and i < 3:
                    mylist.append((self.font, row))
                if i == 2:
                    mylist.append((self.font, row, 'bold'))
                if i > 2:
                    mylist.append(row)
        mylist.append(self.col1)
        mylist.append(self.col2)
        mylist.append(self.col3)
        mylist.append(self.col4)
        mylist.append(self.col5)
        return mylist


if __name__ == '__main__':
    # Test
    ScreenConf(1600, 900).myscreen()

Code: Alles auswählen

"""Private Module"""
from gui_screenconf import ScreenConf

class View(object):

    def __init__(self, controller):
        self.port = prog_check(PROGRAMMNAME)
        print('Port: %s, PID: %s' % (self.port, os.getpid()))
 
        self.root = tk.Tk()
        self.title = "EDV-Work"
        self.root.title(self.title)
        self.controller = controller
        xpos = 0
        ypos = 0
        self.screenx = self.root.winfo_screenwidth()
        self.screeny =  self.root.winfo_screenheight()
        self.root.geometry("%dx%d+%d+%d" % (self.screenx,
            self.screeny, xpos, ypos))

        # Layout Definition
        self.mylayout = ScreenConf(self.screenx, self.screeny).myscreen()
        self.txt = self.mylayout[0]
        self.txt2 = self.mylayout[1]
        self.txt2b = self.mylayout[2]
        self.fluy = self.mylayout[3]
        self.distanzx = self.mylayout[4]
        self.distanzx2 = self.mylayout[5]
        self.distanzx3 = self.mylayout[6]
        self.distanzx4 = self.mylayout[7]
        self.eingabex = self.mylayout[8]
        self.eingabex2 = self.mylayout[9]
        self.fc = self.mylayout[10]
        self.fcw = self.mylayout[11]
        self.fcdg = self.mylayout[12]
        self.fcdr = self.mylayout[13]
        self.bg = self.mylayout[14]
Antworten