QT4 Event preemption: mouse click to get object name
See also the experiment to dump properties.
http://www.linuxquestions.org/questi...nal-app-34716/
Now that we have event preemption ability, let's get simple again and create ui application that can tell the name of a widget by clicking on it.
[It's simpler than you think but I have uploaded the sources and makefile in case my description of this process is too complicated or confusing.]
Preemption for this is necessary because NORMAL mouse events need to be disabled (or consumed) during the call to identify the widgets.
So let's start here if we're using mc2.
Here's the ui file after editing and adding a few widgets for the test.
[The 'hints' tags have been stripped for size reduction... should still work even though the connection editor won't show them in the right places.]
file: src/click_id.ui
edit src/app-main.cpp so it looks like this.
file: src/app-main.cpp
Edit click_id.h and add
Edit click_id.cpp and add
We also need the subclassed QApplication that allows us to do this.
file: src/lqapp.cpp
file: src/lqapp.h
Now we have
1. click_id.ui
2. main.cpp
3, 4. click_id.h and cpp (class declaration and slot definitions)
5, 6. lqapp.h and cpp (the event loop handler)
But we need two more files. If you're using qmake and a pro file, use uic and moc and qmake for this, or with mc2, here's how we can do it.
Here's the dump for my clicking on the middle button at the bottom, the form, and the "Get Name" button (that triggers the event preemption and printout) itself.
And all of the buttons function normally if 'Get Name' is not clicked first. All three Quit buttons will indeed quit when we are not preempting the these events.
I'll upload a working copy of this experiment in case my description of the steps was too complicated.
The d/load is only about 6K.
http://rainbowsally.org/rainbowsally...lick-id.tar.gz
Type 'make'. Run 'main' from the terminal so you can see the dump.
Includes debug info in case you want to see how it works. (I use kdbg >= 5.0)
The Computer Mad Science Team
:-)
http://www.linuxquestions.org/questi...nal-app-34716/
Now that we have event preemption ability, let's get simple again and create ui application that can tell the name of a widget by clicking on it.
[It's simpler than you think but I have uploaded the sources and makefile in case my description of this process is too complicated or confusing.]
Preemption for this is necessary because NORMAL mouse events need to be disabled (or consumed) during the call to identify the widgets.
So let's start here if we're using mc2.
Code:
mc2 -fetch qt4 # makefile template for qt4 mc2 -create qt4-files src/click_id.ui # generate initial fileset # edit click_id.ui and change class from QWidget to QDialog mc2 -run qt4-ui src # get ui: target and paste into mc2.def mc2 -init # generate a self-updating makefile
[The 'hints' tags have been stripped for size reduction... should still work even though the connection editor won't show them in the right places.]
file: src/click_id.ui
Code:
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>click_id</class> <widget class="QDialog" name="click_id"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>400</width> <height>300</height> </rect> </property> <property name="windowTitle"> <string>Form</string> </property> <widget class="QPushButton" name="btnGetName"> <property name="geometry"> <rect> <x>280</x> <y>10</y> <width>102</width> <height>27</height> </rect> </property> <property name="text"> <string>Get &Name</string> </property> </widget> <widget class="QPushButton" name="btnQuit_1"> <property name="geometry"> <rect> <x>30</x> <y>220</y> <width>102</width> <height>27</height> </rect> </property> <property name="text"> <string>Quit &1</string> </property> </widget> <widget class="QPushButton" name="btnQuit_2"> <property name="geometry"> <rect> <x>150</x> <y>220</y> <width>102</width> <height>27</height> </rect> </property> <property name="text"> <string>Quit &2</string> </property> </widget> <widget class="QPushButton" name="btnQuit_3"> <property name="geometry"> <rect> <x>270</x> <y>220</y> <width>102</width> <height>27</height> </rect> </property> <property name="text"> <string>Quit &3</string> </property> </widget> </widget> <resources/> <connections> <connection> <sender>btnQuit_1</sender> <signal>clicked()</signal> <receiver>click_id</receiver> <slot>close()</slot> </connection> <connection> <sender>btnQuit_2</sender> <signal>clicked()</signal> <receiver>click_id</receiver> <slot>close()</slot> </connection> <connection> <sender>btnQuit_3</sender> <signal>clicked()</signal> <receiver>click_id</receiver> <slot>close()</slot> </connection> <connection> <sender>btnGetName</sender> <signal>clicked()</signal> <receiver>click_id</receiver> <slot>onGetID()</slot> </connection> </connections> <slots> <slot>onGetID()</slot> </slots> </ui>
file: src/app-main.cpp
Code:
#include <stdio.h> #include <QtGui/QApplication> #include "click_id.h" #include "lqapp.h" int main(int argc, char *argv[]) { LQApp a(argc, argv); click_id w; w.show(); LQApp::watch = &w; return a.exec(); } ////////////////////////////////////////////////////////////// // filling out LQApp extern bool getting_id; // user defined virtual function bool LQApp::eventHandler(QObject* receiver, QEvent* event) { if(event->type() == QEvent::MouseButtonPress) { if(getting_id) { // 1. find widget under mouse... well, that will be the intended // receiver of the current event if getting_id is true. // // 2. get property of widget on mouse click and do NOT process // this event. int indx; QVariant anytype; indx = receiver->metaObject()->indexOfProperty("objectName"); if(indx < 0) printf("This baby has no 'objectName' property\n"); else { const char* s; anytype = receiver->property("objectName"); printf("objectName: %s\n", s = anytype.toByteArray()); } indx = receiver->metaObject()->indexOfProperty("text"); if(indx < 0) printf("This baby has no 'text' property\n"); else { const char* s; anytype = receiver->property("text"); printf("text: %s\n", s = anytype.toByteArray()); } printf("\n"); getting_id = false; return true; // consumed } } return QApplication::notify(receiver, event); }
Edit click_id.h and add
Code:
public slots: void onGetID();
Code:
bool getting_id; void click_id::onGetID() { getting_id = true; }
We also need the subclassed QApplication that allows us to do this.
file: src/lqapp.cpp
Code:
// lqapp.cpp - preemptive event handling in subclass of QApplication #include "lqapp.h" // today the world, tomorrow the stars... bool LQApp::notify(QObject *receiver, QEvent *event) { // printf("receiver: %s0x%lX: eventType: %d\n", // receiver == watch ? "TARGET -> " : "", // (long)receiver, e->type()); return eventHandler(receiver, event); // user defined virtual } LQApp::LQApp(int &argc, char **argv) : QApplication(argc, argv) { // additional setup } LQApp::~LQApp() { // delete additional setup as req'd } QObject* LQApp::watch; // static, globally accessible
Code:
// lqapp.h #ifndef lqapp_h #define lqapp_h #include <QApplication> // parent class #include <qevent.h> // always used class LQApp : public QApplication { public: LQApp(int &argc, char **argv); ~LQApp(); bool notify(QObject *receiver, QEvent *e); // preemptive event handler virtual bool eventHandler(QObject *receiver, QEvent *e); // let's try this approach static QObject* watch; // ... }; #endif // lqapp_h
1. click_id.ui
2. main.cpp
3, 4. click_id.h and cpp (class declaration and slot definitions)
5, 6. lqapp.h and cpp (the event loop handler)
But we need two more files. If you're using qmake and a pro file, use uic and moc and qmake for this, or with mc2, here's how we can do it.
Code:
make ui make
Code:
$> main objectName: btnQuit_2 text: Quit &2 objectName: click_id This baby has no 'text' property objectName: btnGetName text: Get &Name
I'll upload a working copy of this experiment in case my description of the steps was too complicated.
The d/load is only about 6K.
http://rainbowsally.org/rainbowsally...lick-id.tar.gz
Type 'make'. Run 'main' from the terminal so you can see the dump.
Includes debug info in case you want to see how it works. (I use kdbg >= 5.0)
The Computer Mad Science Team
:-)
Total Comments 0