Klassenproblem

Plattformunabhängige GUIs mit wxWidgets.
Antworten
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Hallo.
Ich arbeite an einem Lagerverwaltungssystem für meine Eltern, und da habe ich ein Problem mit dem wxHtmlWindow.
Ich habe eine neue Klasse basierend auf der alten gemacht:

Code: Alles auswählen

# -*- coding: cp1252 -*-
# ---------------------------------------------------------------------------- #
# SmartStorageManager HTML Fenster                                             #
# Version for Linux, Windows and MacOS                                         #
#                                                                              #
# Code by Armin Ronacher <armin.ronacher@active-4.com>                         #
# (c) Copyright 2004 by Active-4 Software Developement                         #
# http://www.active-4.com                                                      #
# ---------------------------------------------------------------------------- #

from wxPython.wx import *
from wxPython.html import *
import wxPython.lib.wxpTag
from ssm import *

class dlg_html(wxHtmlWindow):
    def __init__(self, parent, id):
        mainframe.__Action = ""
        wxHtmlWindow.__init__(self, parent, id, style=wxNO_FULL_REPAINT_ON_RESIZE)
        lc = wxLayoutConstraints()
        lc.top.SameAs(parent, wxTop, 0)
        lc.left.SameAs(parent, wxLeft, 0)
        lc.right.SameAs(parent, wxRight, 0)
        lc.bottom.SameAs(parent, wxBottom, 0)
        self.SetConstraints(lc)
    def OnLinkClicked(self, linkinfo):
        print "User want's to view "+linkinfo.GetHref()
        if (linkinfo.GetHref() == "ssm:login"):
            mainframe.showMessage("Das ist ein Test") #Fehler!
Aber das geht nicht.
Ich habe es auch schon mit

Code: Alles auswählen

parent.showMessage("Das ist ein Test")
probiert, da kam auch ein Fehler.

Wie kann ich erreichen, dass diese Klasse eine Methode einer anderen Aufruft?

Ach Ja. Nochwas.
Ich erstelle dieses HtmlWindow mit:

Code: Alles auswählen

#Übersichts Seite
        self.nb_index = wxPanel(self, -1, style=0)
        self.notebook.AddPage(self.nb_index, "Übersicht")
        self.nb_index.SetAutoLayout(true)
        self.nb_index_html = dlg_html(self.nb_index, -1)
        self.nb_index_html.LoadPage('frames/index.html')
self.notebook ist ein wxNotebook.

Vielleicht kann mir einer helfen.
Zuletzt geändert von mitsuhiko am Dienstag 9. November 2004, 18:30, insgesamt 1-mal geändert.
TUFKAB – the user formerly known as blackbird
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Hi!

Ich weiß nicht genau was bei dir mainframe ist, aber wenn Du eine Methode von parent aufrufen willst, solltest Du in __init__

Code: Alles auswählen

self.parent = parent
schreiben. Dann kannst Du sie mit

Code: Alles auswählen

self.parent.showMessage(...)
aufrufen.

Gruß, mawe
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Das Problem ist, das mainframe bei mir nb_index erstellt, und das wiederum erstellt sozusagen das HTML Widget.
Das Parent leitet zur Notebookseite.
TUFKAB – the user formerly known as blackbird
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi blackbird,

das sagt weder uns noch der Funktion was mainframe ist. Wie ist denn die genaue Fehlermeldung?


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Hi!

Also ist mainframe praktisch das parent von self.nb_index, oder? Dann übergib das einfach auch beim Aufruf von dlg_html:

Code: Alles auswählen

self.nb_index_html = dlg_html(mainframe, self.nb_index, -1) 
...
class dlg_html(...):
    def __init__(self,mainframe,parent,id):
        self.mainframe = mainframe 
        self.parent = parent
        ....
    def OnLinkClick(...):
        ...
        self.mainframe.showMessage(...)
Aber irgendwie hab ich das Gefühl, das ist nicht das was Du willst, oder? Ist showMessage() überhaupt eine Methode von mainframe?

Gruß, mawe
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Jetzt hab ich s :D
Die Lösung ist die Übergabe des selfs von mainform:

Code: Alles auswählen

class mainframe(wxFrame):
    def __init__(self, *args, **kwds):
        ...
        self.notebook = wxNotebook(self, 1010, style=0)
        
        #Übersichts Seite
        self.nb_index = wxPanel(self, -1, style=0) #wxSUNKEN_BORDER
        self.notebook.AddPage(self.nb_index, "Übersicht")
        self.nb_index.SetAutoLayout(true)
        self.nb_index_html = dlg_html(self.nb_index, -1, self) #3. Parameter
        self.nb_index_html.LoadPage('frames/index.html')

Code: Alles auswählen

class dlg_html(wxHtmlWindow):
    def __init__(self, parent, id, owner):
        self.parent = owner
        wxHtmlWindow.__init__(self, parent, id, style=wxNO_FULL_REPAINT_ON_RESIZE)
        lc = wxLayoutConstraints()
        lc.top.SameAs(parent, wxTop, 0)
        lc.left.SameAs(parent, wxLeft, 0)
        lc.right.SameAs(parent, wxRight, 0)
        lc.bottom.SameAs(parent, wxBottom, 0)
        self.SetConstraints(lc)
    #dfdf
    def OnLinkClicked(self, linkinfo):
        print "User want's to view "+linkinfo.GetHref()
        if (linkinfo.GetHref() == "ssm:login"):
            #print "ACTION TEST"
            self.parent.showMessage("Test", "Titel") 
TUFKAB – the user formerly known as blackbird
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Hi!

Wie ich's gesagt habe .... :cool: :D

Gruß, mawe
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

@mawe: Nicht ganz. Weil mein Parent != dein Parent ist. :D
TUFKAB – the user formerly known as blackbird
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Da kannst du aber nur bei einem Parent sicher sein, bei dem anderen weisst du nie wo der überall seine Instanzen erzeugt hat ;)


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Hi!
blackbird hat geschrieben: Nicht ganz. Weil mein Parent != dein Parent ist.
Doch, die parents sind bei uns gleich (jedenfalls bei dem Programm :D).. Allerdings heisst mein mainframe bei dir owner und ist eine Klasse und ... ach was solls, hauptsache es funktioniert :D

Gruß, mawe
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Ok. Nur noch mal, damit ich es verstehe.
Das übergebene parent ist doch das self des nb_index oder?
Und das übergebene owner ist das self von mainframe.

Bitte klärt mich auf. Ich kenn Python erst 3 Wochen :oops:
TUFKAB – the user formerly known as blackbird
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

self kann jede beliebige Instanz einer Klasse sein, kommt darauf an, über welche Instanz die Methode aufgerufen wurde.
Wenn owner eine Instanz der Klasse mainframe ist, dann ist in owner.methode() das self gleich owner.


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ich weiß nicht genau, ob ich das selbe Problem hab...

Ich hab zwei Frames... Wenn vom Hauptframe das zweite Frame erscheinen soll, bekomme ich den Fehler:
AttributeError: CDselection instance has no attribute 'SetTopWindow'
Ich weiß eigentlich auch nicht woher self.SetTopWindow() kommt... Ich denke es ist ein Teil von wx und kommt evtl. durch wx.InitAllImageHandlers() ???
Somit ist es in der "class CDselection" nicht vorhanden, also auch irgendwie über self übergeben???

Hier ein wenig Code:

Code: Alles auswählen

import wx
import mainFrame
import CDselectFrame

class CDselection:
    def __init__( self ):
        self.CDselectFrame = CDselectFrame.CDselectFrame(None, -1, "")
        self.SetTopWindow(self.CDselectFrame)
        self.CDselectFrame.Show()

class MyApp(wx.App):
    def OnInit(self):
        wx.InitAllImageHandlers()
        self.mainFrame = mainFrame.mainFrame(None, -1, "")
        self.SetTopWindow(self.mainFrame)
        self.mainFrame.Show()

        CDselection()

app = MyApp(0)
app.MainLoop()
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Oh, meine vermutung war richtig, so geht's:

Code: Alles auswählen

import wx
import mainFrame
import CDselectFrame

class CDselection:
    def __init__( self, owner ):
        self = owner
        self.CDselectFrame = CDselectFrame.CDselectFrame(None, -1, "")
        self.SetTopWindow(self.CDselectFrame)
        self.CDselectFrame.Show()

class MyApp(wx.App):
    def OnInit(self):
        wx.InitAllImageHandlers()
        self.mainFrame = mainFrame.mainFrame(None, -1, "")
        self.SetTopWindow(self.mainFrame)
        self.mainFrame.Show()

        CDselection( self )

app = MyApp(0)
app.MainLoop()

Aber ist das eine brauchbare Vorgehensweise??? Für jedes Fenster eine neue Klasse??? Wobei alles in einer zu manschen wird unübersichtlich...

EDIT:
Ne, ist doch nicht so eine gute Idee.... Wenn self=owner ist, kann man in der Klasse keine Funktionen mehr ansprechnen, weil sie in owner gesucht werden :(
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

[KILL]
Zuletzt geändert von jens am Donnerstag 2. Dezember 2004, 16:31, insgesamt 2-mal geändert.
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi jens,

uiuiui ;)

Code: Alles auswählen

class CDselection:
    def __init__( self, owner ):
        self = owner
        self.CDselectFrame = CDselectFrame.CDselectFrame(None, -1, "")
        self.SetTopWindow(self.CDselectFrame)
        self.CDselectFrame.Show()
keine gute Idee self mit owner zu überschreiben.

Code: Alles auswählen

import wx
import mainFrame
import CDselectFrame

class MyApp(wx.App):

    def CDSelection(self):
        self.CDselectFrame = CDselectFrame.CDselectFrame(None, -1, "")
        self.SetTopWindow(self.CDselectFrame)
        self.CDselectFrame.Show() 

    def OnInit(self):
        wx.InitAllImageHandlers()
        self.mainFrame = mainFrame.mainFrame(None, -1, "")
        self.SetTopWindow(self.mainFrame)
        self.mainFrame.Show()

        self.CDSelection()


app = MyApp(0)
app.MainLoop()
nicht getestet!
Sollte ohne extra Klasse das machen was du willst.


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ups... Das hat sich ein wenig überschnitten...

Ich weiß das es mit einer Klasse geht... Ich würd nur gern jedes Fenster/Frame seperat behandeln und nicht alle Funktionen in einer Klasse bauen...



Ok, so geht's:

Code: Alles auswählen

import wx
import mainFrame
import CDselectFrame

class CDselection:
    def __init__( self, owner ):
        self.CDselectFrame = CDselectFrame.CDselectFrame(None, -1, "")
        owner.SetTopWindow(self.CDselectFrame)
        self.CDselectFrame.Show()

        wx.EVT_BUTTON(owner, self.CDselectFrame.button_abbruch.GetId(), self.abbruch)

    def abbruch(self, event):
        self.CDselectFrame.Hide()

class MyApp(wx.App):
    def OnInit(self):
        wx.InitAllImageHandlers()
        self.mainFrame = mainFrame.mainFrame(None, -1, "")
        self.SetTopWindow(self.mainFrame)
        self.mainFrame.Show()

        CDselection( self )
Aber schön ist was anderes...

Zumal... Das ist jetzt MultiThreading :) Naja, wenn das CDselectFrame durch ein Button des mainFrame aufgerufen wird... Kann man den Button mehrmals drücken und es kommt immer ein neues Fenster... Das macht in meinem Fall aber nicht wirklich sinn...
Muß man das per Hand abfragen???
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

dann würde ich den Button wenn ein CDselectFrame da ist unanklickbar machen und wenn das CDselectFrame geschlossen wird wieder anklickbar.

Dookie
[code]#!/usr/bin/env python
import this[/code]
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Gute Idee... Ob man wohl ein ganzes Frame "deaktivieren" kann???
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Nur zur Anmerkung:

Das CDselectFrame macht man besser als wx.Dialog... Dieses kann man dann mit .ShowModal() aufrufen... Damit wird das Hauptfenster automatisch blockiert und das MultiThreading-Effekt ist damit auch weg, weil das Hauptprogramm solange "eingeschlafen" ist...
Antworten