grid und Gnuplot

Fragen zu Tkinter.
Antworten
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

Tag zusammen,

ich hätte noch mal zwei Fragen die eher die Optik betreffen:

Das Layout meines Fensters habe ich mit grid gemacht. Es besteht aus 20 Zeilen und 3 Spalten. In den ersten beiden Spalten sind ein paar Eingabefenster und in der dritten Spalte die Ausgabe-Textbox

Code: Alles auswählen

self.textfenster = ScrolledText(self.root, width=90, height=40, background='white')
		self.textfenster.grid(row=0, rowspan=20, column=2)
Wenn ich jetzt aber das Fenster vergößer, dann zentriert sich alles in der Mitte. Gibt es eine Möglichkeit, dass die Eingabefelder links bleiben und sich das Textfeld in der Größe anpasst, so dass das gesamte Fenster ausgefüllt ist?

Ich habe einige Messpunkte, die ich bisher mit Gnuplot ausgebe (auf OpenLinux 10.1). Kann ich die Kurve auch irgendwie in meinem schon vorhandenen Fenster ausgeben, so dass kein neues Fenster aufgeht? Z. B. in der Textbox oder in einem anderen Element? Ich denke das sähe einfach "schicker" aus.

Schonmal vielen Dank!
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

Hallo,
zeig doch bitte etwas von deinem Code her( am besten die Stelle die du meinst ) .
So muss ich immer raten was du meinst.

Gruss
pyStyler
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

Irgendwie sagst du das immer ;)
Leider bin ich mir nicht so sicher, welcher Code dir da weiterhelfen könnte. Der Code vom Feld "ScrolledText" steht ja da und links daneben stehen nur "Label" und "Entry". Stark gekürzt ungefähr so:
(Denkt euch einfach ein paar der Einrückungen weg ;))

Code: Alles auswählen

class Meas:
   
	def __init__(self):
		self.root = tk.Tk()
	  	self.root.title('MEAS')
	  
	  	self.lab=tk.Label(self.root,text=u"Channel(s): ")
		self.lab.grid(row=2, column=0, sticky=tk.W)
		self.eingabe = tk.Entry(self.root,width=30,background='white')
		self.eingabe.grid(row=2, column=1, sticky=tk.W)
	
		self.volt=tk.Label(self.root,text=u"VOLTAGE (V): ")
		self.volt.grid(row=4, column=0, sticky=tk.W)
		self.veingabe = tk.Entry(self.root,width=10,background='white')
		self.veingabe.grid(row=4, column=1, sticky=tk.W)
                .
                .
                .
                self.textfenster = ScrolledText(self.root, width=90, height=40, background='white')
		self.textfenster.grid(row=0, rowspan=20, column=2)


		self.scan = tk.Button(self.root,text='SCAN', command = self.scan)
		self.scan.grid(row=18, column=1, sticky=tk.E)

		self.save = tk.Button(self.root,text='SAVE', command = self.save)
		self.save.grid(row=19, column=1, sticky=tk.E)

		self.root.mainloop()
Und dieses Textfenster soll sich nun der Größe meines Fensters anpassen können. Wenn ich also das Fenster größer ziehe, soll sich das "Textfenster" mit vergrößern, so dass kein grauer Rand entsteht.

Das Fenster mit Gnuplot mach ich so:

Code: Alles auswählen

import Gnuplot 
                        self.g =Gnuplot.Gnuplot()
			self.g.title('I(V)-Kennlinie')
			self.g.xlabel('Voltage (V)')
			self.g.ylabel('Current (A)')
			self.g('set style data linespoints')
			self.data = list()
                        ...
                       self.data.append([float(self.volt2),float(self.current2)])
                       self.g.plot(self.data)
Aber das ist doch eigentlich auch egal, ich will ja "nur" wissen, ob ich auch direkt in mein Fenster zeichnen kann, mit welchem Programm auch immer...
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

Hi

Code: Alles auswählen

#!/usr/bin/env python

from Tkinter import *


class testFrame(Frame):
    def __init__(self, *args, **params):
            
            apply(Frame.__init__, (self,) + args, params)
            self._parent = None
            if len(args) != 0: self._parent = args[0]

            self._widgets = {}
            self._widgets['label#1'] = Label(self, name='label#1', text='Channel(s)')
            self._widgets['label#1'].grid(column=1, columnspan=3, row=2, sticky='ew')
            
            self._widgets['entry#2'] = Entry(self, name='entry#2', borderwidth=0, 
                            highlightbackground='grey', highlightthickness=1, relief='flat', 
                            textvariable=None)
            self._widgets['entry#2'].grid(column=4, columnspan=3, padx=3, pady=3, row=2, sticky='nesw')
            
            self._widgets['listbox#1'] = Listbox(self, name='listbox#1', borderwidth=1, 
                        height=0, highlightbackground='grey', relief='flat', width=0)
            self._widgets['listbox#1'].grid(column=7, columnspan=7, padx=3, pady=3, row=2, 
                                        rowspan=7, sticky='nesw')
            
            self._widgets['label#2'] = Label(self, name='label#2', text='VOLTAGE(V):')
            self._widgets['label#2'].grid(column=1, columnspan=3, row=4, sticky='ew')
            
            self._widgets['entry#3'] = Entry(self, name='entry#3', borderwidth=1, 
                                    highlightbackground='grey', 
                                    highlightthickness=1, relief='flat', 
                                    textvariable=None, width=10)
            self._widgets['entry#3'].grid(column=4, padx=3, pady=3, row=4)
            
            self._widgets['button#1'] = Button(self, name='button#1', text='SCAN')
            self._widgets['button#1'].grid(column=5, columnspan=2, row=6, sticky='nesw')
            
            self._widgets['button#2'] = Button(self, name='button#2', text='SAVE')
            self._widgets['button#2'].grid(column=5, columnspan=2, row=8, sticky='nesw')
            
         
            self.grid_rowconfigure(1, weight=0, minsize=30)
            self.grid_rowconfigure(2, weight=0, minsize=30)
            self.grid_rowconfigure(3, weight=0, minsize=30)
            self.grid_rowconfigure(4, weight=0, minsize=30)
            self.grid_rowconfigure(5, weight=1, minsize=30)
            self.grid_rowconfigure(6, weight=0, minsize=30)
            self.grid_rowconfigure(7, weight=0, minsize=30)
            self.grid_rowconfigure(8, weight=0, minsize=30)
            self.grid_rowconfigure(9, weight=0, minsize=30)
            self.grid_columnconfigure(1, weight=0, minsize=30)
            self.grid_columnconfigure(2, weight=0, minsize=30)
            self.grid_columnconfigure(3, weight=0, minsize=30)
            self.grid_columnconfigure(4, weight=0, minsize=30)
            self.grid_columnconfigure(5, weight=0, minsize=30)
            self.grid_columnconfigure(6, weight=0, minsize=30)
            self.grid_columnconfigure(7, weight=1, minsize=30)
            self.grid_columnconfigure(8, weight=1, minsize=30)
            self.grid_columnconfigure(9, weight=1, minsize=30)
            self.grid_columnconfigure(10, weight=1, minsize=30)
            self.grid_columnconfigure(11, weight=1, minsize=30)
            self.grid_columnconfigure(12, weight=1, minsize=30)
            self.grid_columnconfigure(13, weight=0, minsize=30)
            self.grid_columnconfigure(14, weight=0, minsize=30)
        

class tkApp( Frame ):
    def __init__(self, master):
        Frame.__init__(self, master)
        
        self.test_frame = testFrame()
        self.test_frame.pack(expand=YES, fill=BOTH)

if __name__ == '__main__':
    root = Tk()
    tkapp = tkApp(root)
    
    root.mainloop()
spaeter mehr....
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

:D So hatte ich mir das vorgestellt :D

Jetzt versuch ich mal deinen Code nachzuvollziehen und anschließend anzupassen, damit dürfte ich erstmal eine Weile beschäftigt sein.

Vielen Dank!!! :D
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

Ich werd am Wochenden wohl nicht dazu kommen weiter zu machen, da ich aber echt das Gefühl hab mit dem Code noch etwas überfordert zu sein schreib ich doch schon mal hin was ich gar nicht und was ich glaub everstanden zu haben:

Was in der Kopfzeile passiert, keine Ahnung.
Die Texte und Felder werden fast wie vorher definiert, nur dass jetzt anstatt

Code: Alles auswählen

		self.volt=tk.Label(self.root,text=u"VOLTAGE (V): ")
		self.volt.grid(row=4, column=0, sticky=tk.W)
das da stehen muss:

Code: Alles auswählen

            self._widgets['label#2'] = Label(self, name='label#2', text='VOLTAGE(V):')
            self._widgets['label#2'].grid(column=1, columnspan=3, row=4, sticky='ew')
Mit den Zeilen

Code: Alles auswählen

            self.grid_rowconfigure(1, weight=0, minsize=30)
            self.grid_rowconfigure(2, weight=0, minsize=30)...
stellt man sich seine Tabelle für das Layout zusammen.

Wie aber erstell ich mir nun eine neue Funktion? Wie ich das vorher gemacht habe:

Code: Alles auswählen

	def scan(self):
geht jetzt ja nicht mehr... :K

Wenn ich jetzt zum Beispiel das hier habe

Code: Alles auswählen

            self._widgets['entry2'] = Entry(self, name='entry2', borderwidth=1,
                            highlightbackground='grey', highlightthickness=1, relief='sunken',
                            textvariable=None)
            self._widgets['entry2'].grid(column=4, columnspan=3, padx=3, pady=3, row=2, sticky='nesw')
kann ich dann wie gewohnt mit

Code: Alles auswählen

self.entry2.get()
und
self.entry2.insert('0','Hallo')
darauf zugreifen?

Bin mal gespannt, wie oft ich noch meinen gesamten Code umschreiben muss :roll:
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

Hi,
das hab ich mir beinahe gedacht, dass du eventuell mit dem Code nicht klar kommen wirst( deshalb schrieb ich später mehr ).

So wieder daheim, bin ich gleich mal deinem Problem nachgegangen.
Ich habe das Gefühl, das es vielen hier schwer fehlt die Logik und das Gui zu trennen. Im Prinzip ist es aber sehr einfach mittels Delegieren in Python zu Programmieren.

Code: Alles auswählen

class testFrame(Frame):
    def __init__(self, *args, **params):
      .
      .
      .
    ''' ab zeile 67 weiter machen'''

    '''hier wird vereinbart an was spaeter die Buttons gebunden werden'''
    def _makeCall1(self, call):
        self._widgets['button#1']['command'] = call
        
    def _makeCall2(self, call):
        self._widgets['button#2']['command'] = call
        
    
class tkApp( Frame ):
    
    def __init__(self, master):
        Frame.__init__(self, master)
        
        self.test_frame = testFrame()
        self.test_frame.pack(expand=YES, fill=BOTH)
        
        self.makeCall1()
        self.makeCall2()
 
        
    ''' da ich nicht weiss, was deine methoden scan und save machen,
    hier mal fuer demo zwcken wie es gehen koennte.'''
        
    def scan(self):
        # der inhalt des entrys mit dem Namen ... wird gelesen...
        self.entry1 = self.test_frame._widgets['entry#2'].get()
        self.entry2 = self.test_frame._widgets['entry#3'].get()
        
        self.text = [ self.entry1, self.entry2  ]
        print self.text 
        
    def save(self):
        self.scan()
        for i in self.text:
            self.test_frame._widgets['listbox#1'].insert(END, (i ))
        
    def makeCall1(self):
        self.test_frame._makeCall1(self.scan)
        
    def makeCall2(self):
        self.test_frame._makeCall2(self.save)
        

if __name__ == '__main__':
    root = Tk()
    tkapp = tkApp(root)
   
    root.mainloop() 
Gruss
pyStyler
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

Ich hab den ganzen Tag lang mein Programm umgeschrieben und jetzt scheint es fast richtig zu funktionieren. Auch wenn ich leider ständig auf neue Fehler stoße...

Allerdings bekomme ich zwei Sachen gar nicht hin:
Erstens den "Titel" des Fensters

Code: Alles auswählen

self.root.title('Titel')
funktioniert ja nicht mehr, aber ich finde leider keinen Befehl, den er nimmt...

Und zweitens hab ich einen Checkbutton

Code: Alles auswählen

		self.gnu=IntVar(self)
		self._widgets['gnubutton'] = Checkbutton(self,text='Graphische Auswertung',variable=self.gnu)
		self._widgets['gnubutton'].grid(column=3, columnspan=3, padx=3, pady=3, row=11)
und wenn ich den betätige, soll eine Aktion ausgeführt werden. Ich habe versucht sie wie bei einem Button auszuführen.

Code: Alles auswählen

	def _makeCall1(self, call):
		self._widgets['scan']['command'] = call

	def _makeCall2(self, call):
		self._widgets['save']['command'] = call
		
	def _makeCall3(self, call):
		self._widgets['gnubutton']['command'] = call

Code: Alles auswählen

class tkApp( Frame ):
   
	def __init__(self, master):
		Frame.__init__(self, master)

		self.meas_frame = Meas()
		self.meas_frame.pack(expand=YES, fill=BOTH)

		self.makeCall1()
		self.makeCall2()
		self.makeCall3()
aber so akzeptiert er das leider nicht!?
Jemand eine Idee, wie man das machen kann?

Schonmal vielen Dank!
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

Hallo,
der Code ist diesmal ausgelagert, da man sonst in diesem Thread nicht mehr antworten kann/könnte. Versuche nachzuvollziehen wie die Methoden aufgerufen werden.

achso ja... title ändern ist auch sehr einfach, siehe unten im Code.


link:http://paste.pocoo.org/show/1418/

Gruss
pyStyler
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

Ups... da hätte ich ja fast von alleine drauf kommen können :oops:
Naja, war gestern ein langer Tag ;)

Dann mal VIELEN VIELEN DANK!!! Ohne Dich hätte ich das nie hinbekommen!

Wenn dieser Thread hier "voll" ist, dann frag ich wegen Gnuplot doch noch mal in einem neuen nach ;)

[EDIT:]Das Prog hat jetzt übrigens schon 565 Zeilen und die Funktion scan hab ich nie reingestellt, da sie alleine schon aus 280 Zeilen besteht.
Antworten