2010-02-17 20 views
6

Ich schrieb ein WxPython-Programm, das ich in WxWidgets übersetze. Das Programm verfügt über ein Bildlauffenster, in dem ein Bild angezeigt wird. Nach Rappin, wxPython In Aktion (Listing 12.1), habe ich eine StaticBitmap in einem Panel verwendet. Beim Durchsuchen der neuesten wxWidgets-Dokumentation habe ich eine dire warning gefunden, die wxStaticBitmap nur für sehr kleine Bilder verwenden soll. Es heißt, "... Sie sollten Ihre eigene Steuerung verwenden, wenn Sie größere Bilder portabel anzeigen möchten." Okay. Zeig es mir. Ich habe meine "eigene Kontrolle" nicht.Wie einfache wxWidgets Bildanzeige erstellen

War Rappin falsch oder ist die Dokumentation veraltet?

Die Frage - ein Neuling, kein Zweifel - ist, was ist der richtige Weg, um ein einfaches Bild-Ansicht-Fenster in WxWidgets zu machen? Ein Drop-In-Ersatz für wxStaticBitmap wäre schön. Ich habe das Programm "image" im wxWidgets-Verzeichnis "samples" untersucht. Es ist so lange ein Krieg und Frieden. Sicher muss es eine Dosenklasse oder ein einfaches Rezept geben.

+0

vielleicht eher als 'Invalidate()', mghie bedeutete 'Refresh()'. (Dies sollte ein Mod sein, um 0 zu beantworten, aber ich sehe nicht, wie das zu erreichen ist.) – contributor

Antwort

3

Lassen Sie sich nicht von der Größe der "Bild" -Stichprobe täuschen, nur ein paar Zeilen Code sind notwendig, um das zu tun, was Sie wollen.

Suche nach der MyImageFrame Klasse in der image.cpp Datei ist es nichts anderes als eine Klasse mit einem eigenen Bitmap-Feld, ein benutzerdefinierten Konstruktor das Bitmap und das Fenster Client-Größe und ein Event-Handler für EVT_PAINT einstellen :

void OnPaint(wxPaintEvent& WXUNUSED(event)) 
{ 
    wxPaintDC dc(this); 
    dc.DrawBitmap(m_bitmap, 0, 0, true /* use mask */); 
} 

Da Sie Ihr Rezept nicht eine Rahmenklasse wollen hier: Sie einen einfachen Nachkommen wxWindow schaffen, die eine ähnlichen Konstruktor, Farbe Handler hat und die Methoden des wxStaticBitmap Duplikate, die Sie in Ihrem Code verwenden. Vielleicht einfach eine Methode, um ein neues Bitmap zu setzen und das Steuerelement auf die neuen Bitmap-Dimensionen zu skalieren.

+0

Ich markiere das als Antwort. Es sieht einfach aus. Ich habe es noch nicht wirklich zur Arbeit gebracht, aber ich habe gerade angefangen. :-) –

+0

Ein aktuelles Arbeitsbeispiel wäre großartig. Ich habe herausgefunden, dass ich "PrepareDC (dc)" nach dem "wxPaintDC dc (this);" Ich habe keine Ahnung, was das ist oder warum es gebraucht wird. Nur Affe - Affen tun. Ich habe es jetzt korrekt angezeigt. Aber ich habe noch einen Mausklick auf das Bild erfassen können. Immer noch kämpfend. Weiter durch den Nebel! –

+0

@Jive: Siehe http://docs.wxwidgets.org/2.8/wx_wxscrolledwindow.html#wxscrolledwindowpreparedc, dies steht jedoch außerhalb des Schreibens eines einfachen 'wxStaticBitmap'-Ersatzes. Für Mausklicks siehe http://docs.wxwidgets.org/2.8/wx_wxmouseevent.html#wxmouseevent, sollte Ihre Klasse in der Lage sein, diese zu handhaben, so dass Sie nur einen Handler verbinden müssen. * view.cpp * im * docvwmdi * -Sample hat eine Canvas-Klasse (Nachkomme von 'wxScrolledWindow'), die sowohl das Zeichnen als auch die Mausverarbeitung übernimmt. – mghie

2
// A scrolled window for showing an image. 
class PictureFrame: public wxScrolledWindow 
{ 
public: 
    PictureFrame() 
     : wxScrolledWindow() 
     , bitmap(0,0) 
    {;} 

    void Create(wxWindow *parent, wxWindowID id = -1) 
    { 
     wxScrolledWindow::Create(parent, id); 
    } 

    void LoadImage(wxImage &image) { 
     bitmap = wxBitmap(image); 
     SetVirtualSize(bitmap.GetWidth(), bitmap.GetHeight()); 
     wxClientDC dc(this); 
     PrepareDC(dc); 
     dc.DrawBitmap(bitmap, 0, 0); 
    } 

protected: 
    wxBitmap bitmap; 

    void OnMouse(wxMouseEvent &event) { 
     int xx,yy; 
     CalcUnscrolledPosition(event.GetX(), event.GetY(), &xx, &yy); 
     event.m_x = xx; event.m_y = yy; 
     event.ResumePropagation(1); // Pass along mouse events (e.g. to parent) 
     event.Skip(); 
    } 

    void OnPaint(wxPaintEvent &event) { 
     wxPaintDC dc(this); 
     PrepareDC(dc); 
     dc.DrawBitmap(bitmap, 0,0, true); 
    } 
private: 
    DECLARE_EVENT_TABLE() 
}; 

BEGIN_EVENT_TABLE(PictureFrame,wxScrolledWindow) 
    EVT_PAINT(PictureFrame::OnPaint) 
    EVT_MOUSE_EVENTS(PictureFrame::OnMouse) 
END_EVENT_TABLE() 
+0

Sie sollten wahrscheinlich keinen Malcode in 'LoadImage()' aufrufen, der Aufruf von 'Invalidate()' sollte ausreichen, das Steuerelement wird dann neu gezeichnet, wenn es für das System geeignet ist. Es ist möglicherweise nicht notwendig oder es kann sogar unmöglich sein, zu dem Zeitpunkt zu malen, an dem 'LoadImage()' aufgerufen wird. – mghie

+0

1> ------ Erstellt: Projekt: Munsell_picker, Konfiguration: Debug Win32 ------ 1> Kompilieren ... 1> main.cpp 1>. \ Main.cpp (114): Fehler C3861: 'Invalidate': Bezeichner nicht gefunden –