Konsole in GUI- Fenster

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

Konsole in GUI- Fenster

Beitragvon mathi » Donnerstag 17. Januar 2008, 15:15

Hi,
ich habe ein Konsolen-Programm geschrieben. Um jetzt nach und nach einzelne Teile Buttons grafisch darzustellen brauche ich z.B. TKInter (ist mir klar). Aber für den Anfang würde ich gerne eine " virtuelle Konsole" in einem Hauptfenster haben, und dann nach und nach einige Auswahlfunktionen über Buttons ersetzen, aber den Hauptteil wie: print und raw_input in der "virtuellen" Konsole laufen lassen.

ist so etwas einfach möglich oder sollte ich umdenken?
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Beitragvon schlangenbeschwörer » Donnerstag 17. Januar 2008, 15:27

Hi mathi,
du kannst einfach mit dem os-modul deine Ein- und Ausgaben umleiten.
Bsp:

Code: Alles auswählen

import Tkinter as tk
import sys
class TkConsole:
    def __init__(self):
        self.console= tk.Text(width=80, height=20)
        self.console.pack()
    def write(self, text):
        self.console.insert("end", text)

c = TkConsole()
sys.stdout = c
print "Ich bin ein Testingteststring"
tk.mainloop()

sys.stdout kanns du ein beliebiges Objekt mit einer "write"-Methode übergeben. Ähnlich gehts mit sys.stdin und sys.stderr.
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

Beitragvon mathi » Donnerstag 17. Januar 2008, 15:42

vielen Dank, das war im Grunde was ich suche, mit dem kleinen Problem, das ich keine Interaktion habe:

Code: Alles auswählen

# -*- coding: cp1252 -*-
import Tkinter as tk
import sys
class TkConsole:
    def __init__(self):
        self.console= tk.Text(width=80, height=20)
        self.console.pack()
    def write(self, text):
        self.console.insert("end", text)
c = TkConsole()
sys.stdout = c
print "Ich bin ein Testingteststring"

p=eval(raw_input("Eingabewert= "))
a=3
b=5
c=a+b
print 'p=%0.2f' % p
print c
f=open("foo.txt","w") # öffne upatemodus
f.write ("test2")
f.close()
tk.mainloop()


--- ich hoffe ich habe mich verständlich machen können---
ich möchte halt mit raw_input werte empfangen und weiterverarbeiten.
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Donnerstag 17. Januar 2008, 21:34

Unter PyGTK gibt es dafür VTE.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

Beitragvon mathi » Freitag 18. Januar 2008, 07:32

Wie kann ich das unter Windows schaffen ?? :?:

Wichtig ist mir, dass ich dann mit pyinstaller eine .exe erstellen kann, die auch an Fremdrechnern lauffähig ist.
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

Beitragvon Zap » Freitag 18. Januar 2008, 08:42

Hi mathi.

Du kannst dir das raw_input sparen wenn du deine Eingabeaufforderung mit eval() interpretierst, da hast du nichts anderes als ein input().

Code: Alles auswählen

C:\>python
Python 2.5 (r25:51908, Sep 19 2006, 09:52:17) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> p=eval(raw_input("Eingabbewert= "))
Eingabbewert= sys.exit(0)

C:\>
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

Beitragvon mathi » Freitag 18. Januar 2008, 08:49

@Zap

eval(raw_input()) bedeutet dass ich einen String einlese mit raw_input und diesen dann als Zahl interpretiere (aus Sicherheitsgründen) - so raten es einige hier im Forum und ich finde das plausibel :D

hilft mir das ´bei meinem Problem? Begreife ich leider nicht :oops:
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

Beitragvon Zap » Freitag 18. Januar 2008, 09:10

Sorry das ich dir bei deinem eigentlichen Problem nicht helfen kann, da ich weder ausreichen TK erfahrung hab und auch für andere GUI Frameworks gerade keine Lösung parat hab.

Ich wollte dich nur darauf aufmerksam machen das deine Syntax meiner Meinung nach nicht sicherer ist als ein normales input() weil du auch jeden String als code interpretierst.
Guck dir mal meinen Log oben genauer an, dann weißt du was ich meine.
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

Beitragvon mathi » Freitag 18. Januar 2008, 09:35

@Zap
Im Grunde hättest Du recht.
Ich habe es bis jetzt so gemacht:

-wenn eine zahl erwartet wird: eval(raw_input())
-wenn ein String erwartet wird: raw_input()

CM hat geschrieben:Nein, natürlich nicht. Aber input() hat so seine Haken:

Code: Alles auswählen

input(...)
    input([prompt]) -> value
   
    Equivalent to eval(raw_input(prompt)).

D. h. für Dich, wenn Du wirklich nichts Anderes machen willst, ist das ok. Aber sonst kannst Du Dir Sicherheitslücken einbauen.

Gruß,
Christian


BlackJack hat geschrieben:Sicherheit ist immer ein Problem wenn man sich erst einmal an `input()` gewöhnt weil's so schön einfach ist, hat man das früher oder später auch in wichtigem Quelltext oder es gelangt per copy'n'paste aus "unwichtigem" Quelltext in ein wichtiges Programm.

Ab Python 3.0 verhält sich `input()` dann auch wie `raw_input()`, da kann man also jetzt schon den sauberen Weg lernen und verwenden.


@all
Aber back to topic:

Hat keiner eine idee: Ich kann leider mit folgender Lösung nur wenig anfangen, obwohl das doch genau das richtige zu sein scheint:
http://www.python-forum.de/topic-7566.h ... tin+thurau
BlackJack

Beitragvon BlackJack » Freitag 18. Januar 2008, 09:57

Doch noch einmal zum `eval()`: Damit wandelst Du die Zeichenkette nicht in eine Zahl um ─ sie wird als Python-Quelltext angesehen und ausgeführt. Egal welchen Quelltext man da eingibt; also letztlich genau das gleiche was `input()` macht. Zahlen kommen da nur zufällig heraus, wenn die Eingabe auch wirklich eine Zahl war.

Um eine Zeichenkette in eine Zahl um zu wandeln, und auch *nur* das, muss man `int()` oder `float()` anstelle von `eval()` verwenden, je nach dem was für einen Typ man haben möchte.
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

Beitragvon mathi » Freitag 18. Januar 2008, 10:20

ok habe ich begriffen und geändert:

Code: Alles auswählen

 p=float(raw_input("Eingabewert= "))



Mein Problem mit der Konsole bleibt aber :cry:
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

Beitragvon mathi » Montag 21. Januar 2008, 07:54

keiner eine Idee bzw. Hilfe??
BlackJack

Beitragvon BlackJack » Montag 21. Januar 2008, 09:15

Das "einfachste" wäre es wahrscheinlich so eine "Konsole" aus einem `Text`-Widget für die Ausgaben und einem `Entry` für die Eingaben zu programmieren, und das über Sockets mit Deinem ``print``/`raw_input()` verwendenden Quelltext so zu verbinden, dass `sys.stdin` und `sys.stdout` mit dieser Konsole verbunden sind.

Das Hauptproblem ist, dass bei ``print``/`rawinput()` Dein Programm die zeitliche Abfolge bestimmt, GUIs aber ereignisbasiert sind, d.h. der Anwender letztendlich bestimmt wann welcher Code ausgeführt wird. Beides zu mischen verträgt sich nicht so besonders gut.

Oder Du ersetzt `raw_input()` durch eine Funktion die jedesmal ein Fenster mit dem Prompt und einem Entry aufmacht. Das ist zwar einfacher, aber für den Benutzer eine ziemlich lästige GUI.

Im Idealfall hast Du beim bisherigen Quelltext Anwendungslogik und UI voneinander getrennt. Dann kannst Du Deine GUI Stück für Stück aufbauen. Es ist zwar dann erst zum Schluss der ganze Funktionsumfang verfügbar, aber es gibt immer eine funktionierende Teilmenge davon.
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

Beitragvon nkoehring » Montag 21. Januar 2008, 09:19

mathi hat geschrieben:ok habe ich begriffen und geändert:

Code: Alles auswählen

 p=float(raw_input("Eingabewert= "))


Ich will dir noch nen Tipp dazu in Form eines kleinen Auszugs geben:

Code: Alles auswählen

In [9]: float("bla")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)

D:\Eigene Dateien\devel\<ipython console> in <module>()

ValueError: invalid literal for float(): bla


Du solltest also nicht einfach so umwandeln. Machs lieber ungefaehr so:

Code: Alles auswählen

while True:
    value = raw_input("Eingabewert? ")
    try:
        value = float(value)
        break
    except ValueError:
        print "Na das ist aber keine Zahl!"


Das wirkt jetzt vielleicht alles total umstaendlich gegenueber der eval- oder input-Variante, aber Programmabstuerze aus Faulheit des Programmierers bringen dem User nicht viel Freude ;)



mathi hat geschrieben:Mein Problem mit der Konsole bleibt aber :cry:
Sorry for that :oops:
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

Beitragvon mathi » Montag 21. Januar 2008, 10:23

@nkoehring:

hossa, das bringt bei 50 Eingabeabfragen auch 50 while-Schleifen richtig??

hmmm :shock:

@BlackJack:

das hört sich für mich kompliziert an, da ich erst seit 2 Monaten überhaupt programmiere. Ich glaube ich muß das lassen und auf konsole bleiben.

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder