Seite 1 von 1

Klassenproblem

Verfasst: Montag 8. November 2004, 18:13
von mitsuhiko
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.

Verfasst: Montag 8. November 2004, 18:26
von mawe
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

Verfasst: Montag 8. November 2004, 18:42
von mitsuhiko
Das Problem ist, das mainframe bei mir nb_index erstellt, und das wiederum erstellt sozusagen das HTML Widget.
Das Parent leitet zur Notebookseite.

Verfasst: Montag 8. November 2004, 18:56
von Dookie
Hi blackbird,

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


Gruß

Dookie

Verfasst: Montag 8. November 2004, 20:31
von mawe
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

Verfasst: Dienstag 9. November 2004, 04:09
von mitsuhiko
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") 

Verfasst: Dienstag 9. November 2004, 05:35
von mawe
Hi!

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

Gruß, mawe

Verfasst: Dienstag 9. November 2004, 17:51
von mitsuhiko
@mawe: Nicht ganz. Weil mein Parent != dein Parent ist. :D

Verfasst: Dienstag 9. November 2004, 17:54
von Dookie
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

Verfasst: Dienstag 9. November 2004, 18:01
von mawe
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

Verfasst: Dienstag 9. November 2004, 18:32
von mitsuhiko
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:

Verfasst: Dienstag 9. November 2004, 19:32
von Dookie
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

Verfasst: Donnerstag 2. Dezember 2004, 16:09
von jens
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()

Verfasst: Donnerstag 2. Dezember 2004, 16:14
von jens
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 :(

Verfasst: Donnerstag 2. Dezember 2004, 16:26
von jens
[KILL]

Verfasst: Donnerstag 2. Dezember 2004, 16:29
von Dookie
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

Verfasst: Donnerstag 2. Dezember 2004, 16:32
von jens
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???

Verfasst: Donnerstag 2. Dezember 2004, 17:13
von Dookie
dann würde ich den Button wenn ein CDselectFrame da ist unanklickbar machen und wenn das CDselectFrame geschlossen wird wieder anklickbar.

Dookie

Verfasst: Donnerstag 2. Dezember 2004, 20:19
von jens
Gute Idee... Ob man wohl ein ganzes Frame "deaktivieren" kann???

Verfasst: Sonntag 5. Dezember 2004, 00:49
von jens
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...