Link in MessageDialog?

Plattformunabhängige GUIs mit wxWidgets.
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

Hallo,

stehe gerade vor einem Problem und hoffe, dass mir jemand auf die Sprünge helfen kann!?
Und zwar hab ich eine einfache DialogBox (wx.MessageDialog) mit ein paar Infos drin. Nun möchte ich gerne "Links" einfügen. Also wenn man auf so einen Link klickt, soll eine weitere DialogBox mit zusätzlichen Informationen erscheinen. Hab schon die wx Demo durchgeschaut aber nichts zum Thema gefunden?

Gruß
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hallo blubber!

Das kann wx.MessageDialog nicht. Du musst dir selber mit wx.Dialog einen Dialog erstellen. Dort kannst du dann auch wx.lib.hyperlink für die Links verwenden.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

ok danke. Das ist ja blöd. Nagut, werd mal rumstöbern.
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

steh grad irgendwie aufm Schlauch. Also: Ich ruf innerhalb der Classe A bei Betätigung eines Buttons eine Funktion X auf. In der Funktion X steht folgender Code:

Code: Alles auswählen

self.info = Info(self, -1, "This is a Dialog", size=(350, 200), 
                                style = wx.DEFAULT_DIALOG_STYLE)
self.info.CenterOnScreen()
Die Klasse "Info" befindet sich im gleichen Modul und enthält folgenden Code:

Code: Alles auswählen

class Info(wx.Dialog):
    def __init__(self, parent, ID, title, size=wx.DefaultSize, pos=wx.DefaultPosition, 
            style=wx.DEFAULT_DIALOG_STYLE
            ):        
        print "Initialisierung Info"
        
        pre = wx.PreDialog()
        pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP)
        pre.Create(parent, ID, title, pos, size, style)
        self.PostCreate(pre)
Ich bekomm aber eine Fehlermeldung, wenn ich dieses ausführe und weis nicht warum:
Type Error: argument number 2: a 'wxWindow *' is expected, ...
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Du vergisst ja auch, Info.__init__ das `parent`-Argument mitzugeben.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

was muss man denn für parent übergeben? Weil ich hab das Beispiel aus der wx Demo und da wird auch kein parent übergeben!? Also ich seh jedenfalls mal net wie/wo...
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

weis das niemand, was man als parent übergeben muss/kann?
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hallo blubber!

Vielleicht kannst du damit etwas anfangen:
http://www.python-forum.de/topic-11487.html

Im Beispiel verzichte ich aber auf das Fragezeichen in der Titelleiste. Das brauchte ich noch nie und deshalb weiß ich auch nicht ob es genügt, ``None`` als parent zu übergeben. Beim normalen Dialog wie auch beim Frame ist ``None`` erlaubt.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

Hallo Gerold,

danke für das Beispiel, funktioniert soweit sehr gut. Jetzt hab ich allerdings noch ein Problem, und zwar enthält mein eingefügter Text manchmal recht lange Zeilen. Nun macht er automatisch das Fenster so breit, wie die längste Zeile ist, was blöd ist, weil das Fenster dann ungefähr zwei Bildschirmbreiten hat :)
Kann man die maximale Größe des Fensters festlegen, damit er dann einfach automatisch Zeilenumbrüche macht?
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

blubber hat geschrieben:Kann man die maximale Größe des Fensters festlegen, damit er dann einfach automatisch Zeilenumbrüche macht?
Hallo Blubber!

Man kann den Text umbrechen:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-

import wx
from wx.lib.wordwrap import wordwrap

wx.SetDefaultPyEncoding("iso-8859-15")


class MyMessageDialog(wx.Dialog):
   
    def __init__(self, parent = None, title = "Example"):
        wx.Dialog.__init__(self, parent, -1, title)
       
        #...
        
        # Hinweistext
        message = (
            u"Das ist immer so eine Sache mit diesen Texten. Man weiß "
            u"nie was man so schreiben soll. Aber irgendwie möchte man "
            u"doch etwas an Text zusammen bekommen..."
        )
        message = wordwrap(message, 400, wx.ClientDC(self))
        
        lab_message = wx.StaticText(self, label = message)
        hbox_content.Add(lab_message, 1, wx.ALL, 5)
       
# ...
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

hmm ok..plöd. Kann es sein, dass es wordwrap erst ab Python 2.5 gibt? Ich bekomm nämlich ne Fehlermeldung, dass es das Modul nicht gibt...
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

blubber hat geschrieben:hmm ok..plöd. Kann es sein, dass es wordwrap erst ab Python 2.5 gibt?
Hallo blubber!

Hast du evt. diese Zeile übersehen?

Code: Alles auswählen

from wx.lib.wordwrap import wordwrap
Ansonsten gilt wie immer: Komplettes Traceback posten.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

Hallo Gerold,

nein, ich habe den Import nicht vergessen, deshalb kam ich ja zu meiner Vermutung, weil die Fehlermeldung exakt auf die Zeile verweist, in der ich das Modul importieren möchte:

from wx.lib.wordwrap import wordwrap
ImportError: No module named wordwrap

Gruß
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

blubber hat geschrieben:ImportError: No module named wordwrap
Hallo blubber!

Hier ist der Quellcode von wordwrap.py:

Code: Alles auswählen

#----------------------------------------------------------------------
# Name:        wx.lib.wrap
# Purpose:     Contains a function to aid in word-wrapping some text
#
# Author:      Robin Dunn
#
# Created:     15-Oct-2006
# RCS-ID:      $Id: wordwrap.py,v 1.1 2006/10/16 19:49:38 RD Exp $
# Copyright:   (c) 2006 by Total Control Software
# Licence:     wxWindows license
#----------------------------------------------------------------------



def wordwrap(text, width, dc, breakLongWords=True):
    """
    Returns a copy of text with newline characters inserted where long
    lines should be broken such that they will fit within the given
    width, on the given `wx.DC` using its current font settings.  By
    default words that are wider than width will be broken at the
    nearest character boundary, but this can be disabled by passing
    ``False`` for the ``breakLongWords`` parameter.
    """

    wrapped_lines = []
    text = text.split('\n')
    for line in text:
        pte = dc.GetPartialTextExtents(line)
        idx = 0
        start = 0
        startIdx = 0
        spcIdx = -1
        while idx < len(pte):
            # remember the last seen space
            if line[idx] == ' ':                
                spcIdx = idx

            # have we reached the max width?
            if pte[idx] - start > width and (spcIdx != -1 or breakLongWords):
                if spcIdx != -1:
                    idx = spcIdx + 1
                wrapped_lines.append( line[startIdx : idx] )
                start = pte[idx]
                startIdx = idx
                spcIdx = -1

            idx += 1

        wrapped_lines.append( line[startIdx : idx] )

    return '\n'.join(wrapped_lines)
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

ok nun gehts. Vielen Dank.
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

Hello again :)

Also ich habs nun soweit hinbekommen, dass ich ein wx.Dialog - Fenster erstellt habe und darin Links enthalten sind. Nun möchte ich aber, dass wenn man auf einen Link klickt, nicht der Browser mit einer URL geöffnet wird, sondern ein normales wx.MessageDialog inklusive ein paar Anzeigedaten.....

geht das irgendwie?

Gruß

*EDIT*
Also quasi einfach eine Funktion aufrufen, wenn man auf einen Link klickt. Innerhalb dieser Funktion kann ja dann der Code für den MessageDialog sein. Direkt als URL einen Funktionsnamen angeben hat net wirklich funktioniert :(
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

blubber hat geschrieben:Nun möchte ich aber, dass wenn man auf einen Link klickt, nicht der Browser mit einer URL geöffnet wird, sondern ein normales wx.MessageDialog
Hallo blubber!

Schau dir doch die Demo des "HyperLinkCtrl" noch einmal an. Dort wird gezeigt, wie du beim Klick auf den Hyperlink einen Eventhandler aufrufen kannst.

Ungefiltert aus der Demo kopiert:

Code: Alles auswählen

        # Intense link examples..
        self._hyper3 = hl.HyperLinkCtrl(self, wx.ID_ANY, "wxPython Mail Archive",
                                        URL="http://lists.wxwidgets.org/")
        sizer.Add(self._hyper3, 0, wx.ALL, 10)
        self._hyper3.Bind(hl.EVT_HYPERLINK_RIGHT, self.OnRightLink)
        
        self._hyper3.SetLinkCursor(wx.CURSOR_QUESTION_ARROW)
        self._hyper3.SetColours("DARK GREEN", "RED", "NAVY")
        self._hyper3.SetUnderlines(False, False, False)
        self._hyper3.EnableRollover(True)
        self._hyper3.SetBold(True)
        self._hyper3.DoPopup(False)
        self._hyper3.UpdateLink()


        self._hyper4 = hl.HyperLinkCtrl(self, wx.ID_ANY,
                                        "Open Google In Current Browser Window?",
                                        URL="http://www.google.com")
        sizer.Add(self._hyper4, 0, wx.ALL, 10)
        self._hyper4.Bind(hl.EVT_HYPERLINK_LEFT, self.OnLink)
        self._hyper4.SetToolTip(wx.ToolTip("Click link for yes, no, cancel dialog"))
        self._hyper4.AutoBrowse(False)


        


    def OnLink(self, event):
        # Goto URL, demonstrates attempt to open link in current window:
        strs = "Open Google In Current Browser Window "
        strs = strs + "(NO Opens Google In Another Browser Window)?"
        nResult = wx.MessageBox(strs, "HyperLinkCtrl", wx.YES_NO |
                                wx.CANCEL | wx.ICON_QUESTION, self)

        if nResult == wx.YES:
            self._hyper4.GotoURL("http://www.google.com", True, True)
        elif nResult == wx.NO:
            self._hyper4.GotoURL("http://www.google.com", True, False)
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

Danke :oops:
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

kann man eigentlich einem Event einen Parameter übergeben ?
Also wenn man das Beispiel der Demo her nimmt:

Code: Alles auswählen

self._hyper4.Bind(hl.EVT_HYPERLINK_LEFT, self.OnLink(uebergabe)) 
Dass hier an die Funktion self.OnLink der Parameter "uebergabe" übergeben wird !?

wenn ich

Code: Alles auswählen

def OnLink(self, event, uebergabe)
oder sowas mache, dann heisst es immer, dass 3 Variable empfangen aber nur 2 übergeben werden !?

Gruß
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

blubber hat geschrieben:kann man eigentlich einem Event einen Parameter übergeben?
Hallo blubber!

z.B. mit lambda:

Code: Alles auswählen

self._hyper4.Bind(hl.EVT_HYPERLINK_LEFT, lambda event: self.OnLink(event, uebergabe))

Code: Alles auswählen

def OnLink(self, event, uebergabe = None)
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Antworten