```c QMenu* mainMenu; QAction* action1 = mainMenu->addAction(QIcon(":/icon1.png"),"Entry1" ); connect( action1, &QAction::triggered, this, &MyClasss::mySlot1, Qt::UniqueConnection ); QAction* action2 = mainMenu->addAction(QIcon(":/icon2.png"), "Entry2" ); connect( action2, &QAction::triggered, this, &MyClasss::mySlot2, Qt::UniqueConnection ); // --- SUBMENU -------------------------------------------------------- QMenu* subMenu = mainMenu->addMenu( QIcon(":/menuIcon.png"), "SubMenu Title" ); QAction* subAction1 = mainMenu->addAction(QIcon(":/subIcon1.png"),"subEntry1" ); connect( subAction1, &QAction::triggered, this, &MyClasss::subSlot1, Qt::UniqueConnection ); QAction* subAction2 = mainMenu->addAction(QIcon(":/subIcon2.png"), "subEntry2" ); connect( subAction2, &QAction::triggered, this, &MyClasss::subSlot2, Qt::UniqueConnection ); // -------------------------------------------------------------------- QAction* action3 = mainMenu->addAction(QIcon(":/icon3.png"),"Entry3" ); connect( action3, &QAction::triggered, this, &MyClasss::mySlot3, Qt::UniqueConnection ); QAction* action4 = mainMenu->addAction(QIcon(":/icon4.png"), "Entry4" ); connect( action4, &QAction::triggered, this, &MyClasss::mySlot4, Qt::UniqueConnection ); ```
Submenu in a QMenu.
Adding a submenu to a QMenu is really easy, and you add nested submenus if you want:
Simple and fast signal-slot system in C++.
This is a simple and fast implementation of a signal-slot system in C++.
It's goal is to be simple and as fast as possible.For that, we create a signal-slot system tha is specific for our use case, that's the price we pay for a fast system.
In this case we create callbacks that take an integer value, but it could be adapted for any oyhter use case.
First we need a base class for our callbacks.
We need this class to virtualize the call() function and easily link callbacks in order to create a list.
It is implemented as a linked list: each callbacks holds a pointer to the function to call and a pointer to the next callback.
```c class CallBackBase { public: CallBackBase(){;} virtual ~CallBackBase(){;} virtual void call( int ){;} CallBackBase* nextCallBack; }; ```
Here we have our callback class.
We create callbacks with an object and a member funtion to call:
```c template <class Obj> class CallBack : public CallBackBase { friend class Signal; public: CallBack( Obj* object, void (Obj::*func)(int) ) : CallBackBase() { m_object = object; m_func = func; nextCallBack = 0; } ~CallBack() {;} virtual void call( int val ) override { (m_object->*m_func)(val); } private: Obj* m_object; void (Obj::*m_func)(uint8_t); }; ```
And this is our signal class:
We can add callbacks with the function connect() and remove callbacks with the function disconnect().
On emitValue() we call all the callbacks with an integer value as argument:
```c class Signal { public: Signal() { m_slot = 0; } ~Signal() // Free resources created { CallBackBase* slot = m_slot; while( slot ) // delete slots { CallBackBase* slotDel = slot; slot = slot->nextCallBack; delete slotDel; } } template <class Obj> void connect( Obj* obj, void (Obj::*func)(int) ) { CallBack<Obj>* slot = new CallBack<Obj>( obj, func ); slot->nextCallBack = m_slot; m_slot = slot; } template <class Obj> void disconnect( Obj* obj, void (Obj::*func)(int) ) { CallBackBase* preSlot = 0; CallBackBase* posSlot = m_slot; while( posSlot ) { CallBack<Obj>* cb = dynamic_cast<CallBack<Obj>*>(posSlot); if( cb->m_object == obj && cb->m_func == func ) { if( preSlot ) preSlot->nextCallBack = posSlot->nextCallBack; else m_slot = posSlot->nextCallBack; delete posSlot; break; } preSlot = posSlot; posSlot = posSlot->nextCallBack; } } void emitValue( int val ) // Calls all connected CallBacks { CallBackBase* slot = m_slot; while( slot ) { slot->call( val ); slot = slot->nextCallBack; } } private: CallBackBase* m_slot; }; ```
To use it we create signals, connect callbacks and call emitValue() when needed.
```c AnObjectClass* anObject = new AnObjectClass(); OtherObjectClass* otherObject = new OtherObjectClass(); ThirdObjectClass* thirdObject = new ThirdObjectClass(); OtherObjectClass* otherObject2 = new OtherObjectClass(); Signal on_write; on_write.connect( anObject, &AnObjectClass::writeFunc ); on_write.connect( otherObject, &OtherObjectClass::otherFunc ); Signal on_read; on_read.connect( thirdObject, &ThirdObjectClass::readFunc ); on_read.connect( otherObject2, &OtherObjectClass::someFunc ); void on_write_event( int value ) { on_write.emitValue( value ); } void on_read_event( int value ) { on_read.emitValue( value ); } ```
Subscribe to:
Posts (Atom)
Fast linked list without list
If you need a very fast way to iterate over a list of objects and call the same method on all of them, then here is a posible solution. Der...
-
Sometimes is useful resizing a QListWidget to the size of its content. This is one way to do it. Don't forget resizing again when you...
-
Adding a submenu to a QMenu is really easy, and you add nested submenus if you want: ```c QMenu* mainMenu; QAction* action1 = mainMenu...