[Qt-interest] QStateMachine without MainWindow

Benjamin bebl at mageta.org
Tue May 10 21:58:45 CEST 2011


Am 10.05.2011 13:45, schrieb Bo Thorsen:
>
> Why do you insist on a Qt solution for this? Just read it with standard
> C or C++ code. If you need to have the Qt event loop running, then do
> the reading in a thread and set up queued signals for sending the chars
> to other threads.
>
> Just because Qt is a *very* big hammer, not all problems are nails :)
>
Well, that's what I suggested days ago. It is simple, though you have to 
do the terminal-handling with os-level-functions.. if you need more than 
one os.. do it with #ifdef's

As a matter of fact, out of curiosity I wrote a simple application which 
does the terminal-handling, like I suggested it.

#### eventhandlerapp.h

#ifndef EVENTHANDLERAPP_H
#define EVENTHANDLERAPP_H

#include <QObject>
#include <QCoreApplication>
#include <QDebug>
#include <QEvent>
#include <QKeyEvent>
#include <QThread>

class StdinHandler : public QThread {
     Q_OBJECT
     public:
         explicit StdinHandler(QObject * parent) : QThread(parent) {}

     protected:
         void run ();

     signals:
         void keyPressed( QEvent * e );
};

class EventHandlerApp : public QCoreApplication {
     Q_OBJECT
     public:
         explicit EventHandlerApp(int & argc, char ** argv) :
QCoreApplication(argc, argv) {};

         static int exec ();

     protected slots:
         bool event ( QEvent * e );
};

#endif // EVENTHANDLERAPP_H

#### ! eventhandlerapp.h
#### eventhandlerapp.cpp

#include "eventhandlerapp.h"

#include <stdio.h>
#include <termios.h>
#include <unistd.h>

void StdinHandler::run() {
     unsigned char input;
     struct termios oldt, newt;

     tcgetattr( STDIN_FILENO, &oldt );
     newt = oldt;
     newt.c_lflag &= ~( ICANON | ECHO );
     tcsetattr( STDIN_FILENO, TCSANOW, &newt );

     for(;;) {
         input = (unsigned char) getchar();

         QKeyEvent * event = new QKeyEvent(QEvent::KeyPress, (int) input,
Qt::NoModifier, QString(input));
         emit keyPressed(event);
     }

     tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
}

bool EventHandlerApp::event ( QEvent * e ) {
     QKeyEvent * input = dynamic_cast<QKeyEvent *>(e);
     if(! input) {
         qDebug()<<"EventHandlerApp::event: sent event is not a QKeyEvent";
     }
     else {
         qDebug()<<"EventHandlerApp::event: key"<<input->text()<<"was
pressed";

         delete e;
         return true;
     }

     return QCoreApplication::event(e);
}

int EventHandlerApp::exec() {
     StdinHandler * handler = new
StdinHandler(EventHandlerApp::instance());

     EventHandlerApp::instance()->connect(handler,
SIGNAL(keyPressed(QEvent*)), SLOT(event(QEvent*)), Qt::QueuedConnection);

     handler->start();

     return EventHandlerApp::instance()->exec();
}

#### ! eventhandlerapp.cpp
#### main()

int
main ( int argc, char ** argv ) {
     EventHandlerApp eha(argc, argv);

     return eha.exec();
}

#### ! main()

This should work fine with every poix-comp. linux.. of course in a 
proper application you would have to handle the exit of a 
EventHandlerApp (stop the StdinHandler) or maybe you would like to 
implement a pause-function for the StdinHandler.
In EventHandlerApp::event() you could handle every key-stroke recognized 
on stdin.

best regards,
- Benjamin



More information about the Qt-interest-old mailing list