automatisches Scrollen in einem Panel

Plattformunabhängige GUIs mit wxWidgets.
Antworten
qweet
User
Beiträge: 119
Registriert: Freitag 2. September 2005, 21:26

Samstag 15. Oktober 2005, 12:00

Hallo,

habe folgenden Code:

Code: Alles auswählen

class MyProgram:
	keycode = 0
	y = 0
	def __init__(self, panel):
		panel.Bind(wx.EVT_CHAR, self.LogKeyEvent)

	def LogKeyEvent(self, evt):
		MyProgram.keycode = evt.GetKeyCode()

		text = wx.StaticText(panel, -1, '')
		text.MoveXY(0, MyProgram.y)
		text.SetLabel(str(self.keycode))

		MyProgram.y = MyProgram.y + 20
Das Programm schreibt bei Tastendruck den Tastenwert auf ein Panel. Immer untereinander.
Ich würde es jetzt gern hinbekommen, dass wenn der untere Rand erreicht ist, automatisch mit Scrollen angefangen wird.

Habe dazu mir die Befehle wx.StaticText.Center oder .ScrollPages und so weiter angeschaut, aber ich bekomme es leider nicht gebacken, ja ich weiß noch nicht einmal ob ich hier an der richtigen Stelle bin.

Aus den Demofiles weiß ich wie man ein ScrolledPanel initiiert. Aber auch hier weiß ich dann nicht mehr weiter.

Irgendwelche Ansätze mit welchen Befehlen das zu lösen wäre?

Grüße,
qweet
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Montag 17. Oktober 2005, 09:40

qweet hat geschrieben:Hallo,

habe folgenden Code:

Code: Alles auswählen

class MyProgram:
	keycode = 0
	y = 0
	def __init__(self, panel):
		panel.Bind(wx.EVT_CHAR, self.LogKeyEvent)

	def LogKeyEvent(self, evt):
		MyProgram.keycode = evt.GetKeyCode()

		text = wx.StaticText(panel, -1, '')
		text.MoveXY(0, MyProgram.y)
		text.SetLabel(str(self.keycode))

		MyProgram.y = MyProgram.y + 20
Das Programm schreibt bei Tastendruck den Tastenwert auf ein Panel. Immer untereinander.
Ich würde es jetzt gern hinbekommen, dass wenn der untere Rand erreicht ist, automatisch mit Scrollen angefangen wird.

Habe dazu mir die Befehle wx.StaticText.Center oder .ScrollPages und so weiter angeschaut, aber ich bekomme es leider nicht gebacken, ja ich weiß noch nicht einmal ob ich hier an der richtigen Stelle bin.

Aus den Demofiles weiß ich wie man ein ScrolledPanel initiiert. Aber auch hier weiß ich dann nicht mehr weiter.

Irgendwelche Ansätze mit welchen Befehlen das zu lösen wäre?

Grüße,
qweet
Hallo, keine Antwort, aber:
Könntest Du ein vollständiges, kurzes Sample hereinstellen?
Warum wird bei LogKeyEvent jedesmal eine neue Instanz von Statictext
erzeugt?
qweet
User
Beiträge: 119
Registriert: Freitag 2. September 2005, 21:26

Montag 17. Oktober 2005, 11:07

Erstmal danke für ne Antwort :)

ein funktionierendes und getestetes Beispiel:

Code: Alles auswählen

import  wx

class MyProgram:
	keycode = 0
	y = 0
	def __init__(self, panel):
		panel.Bind(wx.EVT_CHAR, self.LogKeyEvent)

	def LogKeyEvent(self, evt):
		MyProgram.keycode = evt.GetKeyCode()

		text = wx.StaticText(panel, -1, '')
		text.MoveXY(0, MyProgram.y)
		text.SetLabel(str(self.keycode))
		
		MyProgram.y = MyProgram.y + 20

app = wx.PySimpleApp()

frame = wx.Frame(None, -1, "Test")
panel = wx.Panel(frame, -1)

MyProgram(panel)
frame.Show(True)
app.MainLoop()
Das Programm läuft und gibt untereinander den Tastenwert aus, aber eben nur so lange, bis das Panel zu Ende ist. Alles weitere ist dann vom Benutzer nicht mehr zu sehen. Und das will ich beheben.

Ich hab mir auch die Demofiles angeschaut von wxPython. Es gibt da ein File namens "KeyEvent". Da werden Tastendrücke ausführlich ausgewertet und in einer Liste untereinander geschrieben und das mit Scrollbalken! ;) Nur ist es eben nicht ganz das was ich suche. Ich würde das gern auf einem Panel realisieren.

Ein anderes File; "ScrolledPanel" setzt Scrollbalken auf ein Panel, jedoch ist deren Länge von vornherein festgelegt.
Da wird zum Beispiel eine Linie gezeichnet mit der Länge von 1000 Pixeln und dann ist eben der Scrollbalken auch so lang.
Warum wird bei LogKeyEvent jedesmal eine neue Instanz von Statictext
erzeugt?
Sry, aber das kann ich dir nicht genau sagen. Ich weiß nur, dass, wenn ich es so mache, genau das passiert was ich halt als Ausgabe haben will. Also das mehrere Textausgaben untereinander stehen.

Im Endeffekt habe ich ein sehr einfaches Ziel. Mit der normalen Konsole ist es in NullKommaNix zu erreichen.
Nur ist da eben ein Scrollbalken vorhanden und hier bei wxPython muss ich den noch selber definieren.

Grüße,
qweet
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Montag 17. Oktober 2005, 12:45

Ah, jetzt verstehe ich die Problematik.
Du müsstest direkt auf das Panel ein Control machen.
Ist da jedoch mindestens ein Control, bekommt das Panel keine Key Events mehr.

Hm, darum ist im Python Demo das wx.Window, auf das man klicken
muss (damit es den Focus hat), und diese wx.Window Key Events
werden dann angezeigt.

Man musste hier das auch irgendwie zweiteilen (mit einem Splitterwindow,
wo oben ein wx.Window ist (das den Focus dann hat),
und unten ein Textctrl mit dem Style style=wx.TE_MULTILINE| wx.TE_READONLY
qweet
User
Beiträge: 119
Registriert: Freitag 2. September 2005, 21:26

Dienstag 18. Oktober 2005, 19:16

folgender Code funktioniert und ist getestet.

Jedoch gibt es das Problem, dass, wenn ich das Programm zu lange ausführe und eine Taste drücke, irgendwann der Text ganz unten verwischt. Das ist Mist. Ich hab mir gedacht das könnt mit dem Sizer zusammenhängen. Als ob der dann überdehnt würde.

Code: Alles auswählen

import wx
import wx.lib.scrolledpanel as scrolled

class TestPanel(scrolled.ScrolledPanel):
	def __init__(self, parent):
		scrolled.ScrolledPanel.__init__(self, parent, -1)
	
		sizer = self.sizer = wx.BoxSizer(wx.VERTICAL)
		self.SetSizerAndFit(sizer)
	
		self.Bind(wx.EVT_CHAR, self.LogKeyEvent)

	def LogKeyEvent(self, evt):
		self.Freeze()
		
		text = wx.StaticText(self, -1, "This is just Text")
		
		self.sizer.Add(text)
		self.SetupScrolling()
		
		x, y = self.GetVirtualSize()
	
		wx.CallAfter(self.Scroll, -1, y)
		
		self.Thaw()


class MyApp(wx.App):
	def OnInit(self):
		frame = wx.Frame(None, -1, "Test")
		p = TestPanel(frame)
		frame.Show(True)
		return True


app = MyApp()
app.MainLoop()
Außerdem entspricht das Programm nicht ganz meiner Vorstellung. Ich würde lieber selber die X und Y Koordinaten für die Textobjekte zuweisen.
Habe deswegen noch nen Code, nur funktioniert es halt leider nicht :(

Code: Alles auswählen

import wx
import wx.lib.scrolledpanel as scrolled


class TestPanel(scrolled.ScrolledPanel):
	y = 0
	def __init__(self, parent):
		scrolled.ScrolledPanel.__init__(self, parent, -1)
		self.Bind(wx.EVT_CHAR, self.LogKeyEvent)

	def LogKeyEvent(self, evt):
		self.Freeze()	
		
		text = wx.StaticText(self, -1, "Text")
		text.MoveXY(0, TestPanel.y)
		TestPanel.y  = TestPanel.y + 20
		
		self.SetupScrolling()

		wx.CallAfter(self.Scroll, -1, TestPanel.y)
		
		self.Thaw()


class MyApp(wx.App):
	def OnInit(self):
		frame = wx.Frame(None, -1, "Test")
		p = TestPanel(frame)
		frame.Show(True)
		return True


app = MyApp()
app.MainLoop()
dankbar für jeden ratschlag.
qweet
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Mittwoch 19. Oktober 2005, 09:37

qweet hat geschrieben:folgender Code funktioniert und ist getestet.

Jedoch gibt es das Problem, dass, wenn ich das Programm zu lange ausführe und eine Taste drücke, irgendwann der Text ganz unten verwischt. Das ist Mist. Ich hab mir gedacht das könnt mit dem Sizer zusammenhängen. Als ob der dann überdehnt würde.
Hallo qweet,

leider weiss ich auch nicht weiter.
Wenn hier niemand mehr antwortet, oder Du zu keiner Lösung kommst:

Vielleicht können sie Dir in der wxPython-user Mailing list helfen?
wxPython-users@lists.wxwindows.org
oder über gmane über Newsreader
(NNTP) abbonieren (ist angenehmer :))

gmane.comp.python.wxpython
qweet
User
Beiträge: 119
Registriert: Freitag 2. September 2005, 21:26

Sonntag 23. Oktober 2005, 11:21

Hab das Problem für meine Bedürfnisse gelöst. Hier mein Code:

Code: Alles auswählen

import  wx
import  wx.lib.scrolledpanel as scrolled

class MyProgram(scrolled.ScrolledPanel):
	ToScroll = 0
	y = 0
	def __init__(self, parent):
		self.Scrollpanel = scrolled.ScrolledPanel(parent, -1)
		
		self.Scrollpanel.SetScrollbars(1, 1, 0, 10000)
		
		self.Scrollpanel.Bind(wx.EVT_CHAR, self.LogKeyEvent)
		
	def LogKeyEvent(self, evt):
		text = wx.StaticText(self.Scrollpanel, -1, 'This is just text')
		text.MoveXY(0, MyProgram.y)
		
		MyProgram.y += 20
		
		if MyProgram.y == 200:
			MyProgram.ToScroll += 100
			self.Scrollpanel.Scroll(0, MyProgram.ToScroll)
			
			MyProgram.y = MyProgram.y - 100


app = wx.PySimpleApp()

frame = wx.Frame(None, -1, "Test")

MyProgram(frame)
frame.Show(True)

app.MainLoop()
Antworten