[Gelöst] wxwidgets: wxAutoBufferedPaintDC



  • Glück auf,

    Ich versuche nun schon seit Stunden mit Hilfe der Klasse wxAutoBufferedPaintDC eine einfache Linie auf einem Frame zu malen. Folgendes Minimalbeispiel wird unter ubuntu ohne Murren compiliert:

    #define wxUSE_GRAPHICS_CONTEXT 1
    #include<wx/wx.h>
    #include<wx/dcbuffer.h>
    
    //Deklarationen:
    
    class myframe : public wxFrame {
    	public:
    		myframe(const wxString& title);
    		void OnTimer(wxTimerEvent& event);
    	private:
    		DECLARE_EVENT_TABLE()
    };
    
    class mainapp : public wxApp {
    	public:
    		virtual bool OnInit();
    };
    
    //Implementierung:
    
    bool mainapp::OnInit() {
    	myframe* appframe = new myframe(wxT("Draw"));
    	appframe->Show(true);
    	return true;
    }
    
    IMPLEMENT_APP(mainapp);
    
    myframe::myframe(const wxString& title) : wxFrame(NULL, wxID_ANY, title) {
    	wxTimer timer1(this, -1);
    	timer1.Start(864, false);
    }
    
    void myframe::OnTimer(wxTimerEvent& event) {
    	int height, width;
    	this->GetClientSize(&width, &height);
    
    	wxAutoBufferedPaintDC dbuffer(this);
    	wxColour c_red(255,0,0);
    	wxPen redpen(c_red, 3, wxSOLID);
    	dbuffer.SetPen(redpen);
    	dbuffer.SetBackgroundMode(wxSOLID);
    	dbuffer.DrawLine(wxPoint(0,0), wxPoint(width, height));
    	this->Refresh();
    }
    
    BEGIN_EVENT_TABLE(myframe, wxFrame)
    	EVT_TIMER(-1, myframe::OnTimer)
    END_EVENT_TABLE()
    
    DECLARE_APP(mainapp)
    

    Compiliert hab ich das ganze über die Komandozeile mit

    g++ `wx-config --cppflags` `wx-config --libs` minimalbsp.cpp -o minimalbsp
    

    Nur dass, was gemacht werden soll, nämlich eine fette rote Linie quer über das Fenster zu zeichnen, wird nicht gemacht. Irgendwie kommen mir auch folgende zwei Dinge spanisch vor: erstens dass ich nirgends angeben muss, wie groß der DC überhaupt sein muss und zweitens, dass der DC eigentlich nur innerhalb der Funktion OnTimer existiert und dann vernichtet wird. Sollte das nicht alle Zeichnungen ebenfalls mit löschen? Ich hab mich eben nur für diese Vorgehensweise entschieden, weil sie so ähnlich auch im wxWidgetsbeispiel "samples/drawing/" verwendet wurde. Nur hilft mir dieses Beispiel auch nicht wirklich weiter, wenn ich AutoBufferedPaintDC verwenden will. Außerdem möchte ich außerhalb vom EVT_PAINT() handler arbeiten. Hauptsächlich auch deshalb, weil ich aus dem Beispiel nirgends rauslesen kann, wann ein solches Event überhaupt ausgelöst wird 😞

    Vielen Dank schonmal im Vorraus,

    der Kotfluegel



  • Du musst das ganze auch im Paint-Event abhandeln und nicht in einem Timer.
    Und nein, das löscht nichts. Du musst diese Klasse halt nur erzeugen. Warum genau weiss ich jetzt auch nicht, das sind Implementierungs-Details die mir nicht auf Anhieb geläufig sind. Und nimm doch nen einfachen wxPaintDC...
    Warum überhaupt ein Timer?
    rya.



  • Vielen Dank schonmal für die Antwort.

    Scorcher24 schrieb:

    Du musst das ganze auch im Paint-Event abhandeln und nicht in einem Timer.

    Naja, in der Online-Dokumentation steht es zumindest (in einer der Basisklassen von AutoBufferedPaintDC) drin, dass man damit auch außerhalb des Paint-events arbeiten kann. Der Grund, weshalb ich Paint-Event nicht verwenden will, ist einfach der, weil ich nicht weiß, wie und wann dieser Event ausgelöst wird. Wird der bei der Erstellung, bei der Größenändernung des Fensters ausgelöst, oder brauch ich dafür einen zusätzlichen Befehl?

    Scorcher24 schrieb:

    Und nein, das löscht nichts. Du musst diese Klasse halt nur erzeugen. Warum genau weiss ich jetzt auch nicht, das sind Implementierungs-Details die mir nicht auf Anhieb geläufig sind.

    Jo, das hab ich auch bei meinen eigenen Recherchen noch mitbekommen. AutoBufferedPaintDC zeichnet sogar nur dann, wenn er zerstört wird, indem er den Buffer-Inhalt auf die eigentliche Zeichenfläche kopiert. Nur wie man ihn verwendet, ist mir nicht klar.

    Scorcher24 schrieb:

    Und nimm doch nen einfachen wxPaintDC...

    Naja, aber AutoBufferedPaintDC hat halt den Vorteil das er das Flimmern beim Aktualisieren der Zeichnung durch einen doppelten Buffer verhindert, bzw. den Doppelten Buffer gerade dann nicht verwendet, wenn das schon vom Betriebssystem automatisch getan wird.

    Scorcher24 schrieb:

    Warum überhaupt ein Timer?

    Ja, gut, der Timer gehört nicht unbedingt zu einem Minimalbeispiel. Das Beispiel habe ich aus einem etwas größeren Projekt zusammengestellt, indem ich eine Analog-Uhr implementieren wollte, die mir eine dezimale Uhrzeit anzeigt 😃
    Deswegen auch das Timer-Intervall von 864ms, weil der Tag ja bekanntlich 86400 Sekunden hat. 🤡
    Und deswegen brauch ich halt nen funktionierenden DC, um die Zeiger darzustellen.



  • Also mit einem Paint-Event scheint es problemlos zu funktionieren. Irgendwie wird es mir schon gelingen mein Problem so umzuschreiben, dass es damit geht.


Anmelden zum Antworten