Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien
Toon posts:

[c++] eigen gui, event handling

Pagina: 1
Acties:

Verwijderd

Topicstarter
goeiemorgen allemaal (waar is die koffiesmiley als je em nodig hebt)

ik heb een GUI gemaakt voor gebruik in mn toekomstige apps (vooral games), volledig autonoom mbv SDL (dus fullscreen gfx, geen windows grappen). nu begint het z'n voltooiing te naderen en wordt het tijd om manieren te bedenken waarop ik de gui goed kan gebruiken in mn programma's, en dan doel ik vooral op messaging en handling.

hoe ik het nu heb geimplementeerd is denk ik een beetje vaag, gezien de lappen code die ik er voor nodig heb. ik zal proberen uit te leggen hoe het in elkaar steekt in het huidige model (niet mn sterkste punt, uitleggen, zeker niet 's ochtends, dus vraag gerust om opheldering als het niet duidelijk is)

mn voorbeeld-app is een window met daarin een datagrid met leden (van een sportschool in dit geval). de gebruiker moet hier leden kunnen aanklikken en veranderen, leden kunnen toevoegen, etc. in mn main.cpp include ik "leden.hpp" (en daarmee .cpp dus) waarin al dit moois staat. hier een stukje uit leden_init():

C++:
1
2
3
4
5
6
7
8
9
10
11
12
  win_leden = new window(screen, "Leden");
  win_leden->setcoords(60, 82, SCREEN_WIDTH - 120, SCREEN_HEIGHT - 142);
  win_leden->setbgcolor(255, 255, 255);
  win_leden->setalpha(200);

  handler_win_leden = new c_handler_win_leden();
  win_leden->setmessagehandler(handler_win_leden);

  datagrid *grid_leden = new datagrid(screen);
  win_leden->addview(grid_leden);
  grid_leden->setcoords(0, 0, 0, -22);
  grid_leden->redraw();


so far so good, dit vind ik wel een geslaagde manier om een kadertje op te zetten. maar let op het handler stukje, die 2 regels.. ik heb een base class 'handler' waar ik de 'c_handler_win_leden' van afleid. alles wat gebeurd binnen dat window, dus alle children ervan - de datagrid, maar ook evt andere knoppen die ik ga toevoegen - sturen hun events naar handler_win_leden->message(..); hier de code van de definitie van de afgeleide class:

C++:
1
2
3
4
5
6
class c_handler_win_leden:public handler {
  public:
    c_handler_win_leden() {}
    virtual ~c_handler_win_leden() {}
    void handle_message(void *sender, s_message message);
};


en de implementatie:

(button_voegtoe_lid is een knop in het win_members window, die roept deze functie dus aan als er op geklikt wordt. *sender is het geheugenadres van de knop, in message.message_int zit bijv een _MSG_CLICKED, maar dat is bij een knop natuurlijk logisch dus daar check ik niet op ;))

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void c_handler_win_leden::handle_message(void *sender, s_message message) {
  if (sender == button_voegtoe_lid && !win_voegtoe_lid) {
    win_voegtoe_lid = new window(screen, "Lid toevoegen");
    win_voegtoe_lid->setcoords(220, 230, 260, 340);
    win_voegtoe_lid->setbgcolor(0, 0, 0);
    win_voegtoe_lid->setalpha(200);
    
    handler_win_voegtoe_lid = new c_handler_win_voegtoe_lid();
    win_voegtoe_lid->setmessagehandler(handler_win_voegtoe_lid);
  } else if (sender == button_voegtoe_lid) { // voegtoe lid win already there?
    win_voegtoe_lid->bringtofront();
    win_voegtoe_lid->setfocus();
  }
  if (win_leden && message.message_int == _MSG_CLOSE) {
    // close children
    if (win_voegtoe_lid) {
      delete win_voegtoe_lid;
      win_voegtoe_lid = NULL;
      delete handler_win_voegtoe_lid;
    }
  
    delete win_leden;
    win_leden = NULL;
    delete this;
  }
}


ik heb de hele 'handler_win_voegtoe_lid' implementatie maar achterwege gelaten, want volgens mij is mn probleem hier al wel duidelijk. het wordt allemaal veel te omvangrijk en onduidelijk. om mn subproblemen op te sommen:

- voor elk window moet ik een handler class afleiden en implementeren
- al die handler objecten van subwindows moeten worden gedelete als het hoofdwindow wordt gesloten, en dat moet ik nu dus dubbel coden (in de 'if _MSG_CLOSE' van de hoofdwindowhandler en in die van de subwindows zelf.. maw het al-dan-niet bestaan van de handler pointers is nogal vaag tijdens runtime
- m'n hele message systeem komt me niet helemaal profi over, alleen ik heb dus geen idee hoe dat bij commerciele GUI's werkt
- zelfde voor het hele handler gebeuren

het liefst zou ik gewoon een 'application' class maken waarvan ik mn 'app_leden' afleid, en waarin ik methoden (zo noemt men functies in classes toch?) kan maken die worden aangeroepen in het toepasselijke geval. dus iets als:

(pseudocode)
C++:
1
2
3
4
5
class app_leden : public application {
  void button_lidtoevoegen_onclick();
  void win_leden_onclose();
  void win_lidtoevoegen_onclose();
}


maar ik geloof niet dat het mogelijk is om het adres van een methode aan een knop te 'knop->sethandler()'en (of heb ik dat mis? zeg me dat ik het mis heb! :p) toen ik het probeerde iig mocht het niet van meneer c++..

mijn vragen samenvattend: hoe wordt zo'n eventhandlersysteem normaliter geimplementeerd? hoe houd ik de code zo minimaal en overzichtelijk mogelijk?

hoop dat het zo een beetje duidelijk is. als m'n vragen n00by overkomen; ik ben nog niet extreem ervaren met c++, vergeef me :)

alvast bedankt.. happy codin' :) bazkie

  • dingstje
  • Registratie: Augustus 2002
  • Laatst online: 02-01-2024
Je kan eens neuzen in de documentatie van gtkmm (en eventueel de source ervan lezen): http://www.gtkmm.org/docs...cs/tutorial/html/apb.html

If you can't beat them, try harder


Verwijderd

Topicstarter
tnx, ziet er uit als zeer nuttige info :)
vanavond eens lekker in verdiepen B)

  • Laurens-R
  • Registratie: December 2002
  • Laatst online: 29-12-2024
Je zou het kunnen oplossen mbv function pointers? Hoewel ik nu niet zeker weet of dit de beste methode is.

Een 'basic' oplossing zou dan als volgt zijn:

- Je bedenkt voor jezelf wat voor informatie je een event wilt meegeven. Dat kan bijvoorbeeld het object zijn die de event getriggerd heeft, of aanvullende parameters die te maken hebben met de event. Aan de hand hiervan maak je een functie definitie:

bijvoorbeeld


code:
1
public void OnClick (BaseObject sender, string[] Params)


of zoiets dergelijks.

- Dan implementeer je een systeem waarmee je events kan registreren en koppelen aan UI elementen. Bv met behulp van zelfontworpen collecties/lists of whatever van een object dat een pointer bevat naar het te koppelen object en naar de de event functie. In feite koppelt deze functie dus de function pointer met een object.

Let op dat je hier dus de function pointer conform de eerder genoemde functiedefinitie opstelt.

- Daarna is het een kwestie van events maken en koppelen.

[ Voor 81% gewijzigd door Laurens-R op 30-07-2007 23:25 ]


  • SjonnieX
  • Registratie: Juni 2007
  • Laatst online: 15-04 21:57
Misschien moet je gewoon je begrijpen wat 'virtual' methods zijn (beetje pseudo code Java/C++ ) en ieder type window van BaseWindow afleiden.

Het oproepen van OnCloseWindow() zal nu ALTIJD EERST je afgeleide klasse oproepen!

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class BaseWindow {
   std::list<Window*> childWindows;
 
    virtual void OnCloseWindow() {
        foreach (Window *pWnd : childWindows) {
             pWnd->OnCloseWindow();
        } 
        invalidateBackground();
        delete this;
    }
}  

// leid je WinLeden klasse af van je basis klasse BaseWindow 
class WinLeden : BaseWindow {  
     virtual void OnCloseWindow() {
           // doe hier je specifieke code

          // roep base klasse op.
          BaseWindow::OnCloseWindow();
     }
}

[ Voor 1% gewijzigd door een moderator op 08-08-2007 16:02 . Reden: code tags toegevoegd. ]


Verwijderd

Topicstarter
hmja dat vind ik op de een of andere manier een beetje nasty.. moet ik overal voor elk knopje en dingetje alles af gaan leiden ;)

heb het nu op de qt signals/slots manier gefixed, met boost signals en bind()..

tnx voor de reacties iig, weer flink wat geleerd hiervan :)

[ Voor 18% gewijzigd door Verwijderd op 08-08-2007 15:50 ]

Pagina: 1