[PyQt] [Qt-interest] QStateMachine without MainWindow

emmanuel_mayssat at lynceantech.com emmanuel_mayssat at lynceantech.com
Wed May 11 23:32:31 BST 2011


Thank you it works!
The python version of your code (without minor bugs!!) is below


#!/usr/bin/env python

from PyQt4.QtCore import *
from PyQt4.QtGui  import *

import os
import sys
import termios

def getchar():
    '''
    Equivalent to getchar() 
    '''

    fd = sys.stdin.fileno()
    
    if os.isatty(fd):
        
        old = termios.tcgetattr(fd)
        new = termios.tcgetattr(fd)
        new[3] = new[3] & ~termios.ICANON & ~termios.ECHO
        new[6] [termios.VMIN] = 1
        new[6] [termios.VTIME] = 0
        
        try:
            termios.tcsetattr(fd, termios.TCSANOW, new)
            termios.tcsendbreak(fd,0)
            ch = os.read(fd,7)

        finally:
            termios.tcsetattr(fd, termios.TCSAFLUSH, old)
    else:
        ch = os.read(fd,7)
    
    return(ch)


class StdinHandler(QThread):
    keyPressed = pyqtSignal('PyQt_PyObject')
    def __init__(self, parent=None):
        super(StdinHandler, self).__init__(parent)
    def run(self):
        char = getchar()
        while char:
            print char
            ke = QKeyEvent(QEvent.KeyPress, ord(char), Qt.NoModifier, QString(char))
            self.keyPressed.emit(ke)
            char = getchar()

class EventHandlerApp(QCoreApplication):
    def __init__(self, argv):
        super(EventHandlerApp, self).__init__(argv)
    def exec_(self):
        handler = StdinHandler(self)
        self.connect(handler, SIGNAL('keyPressed(PyQt_PyObject)'), self.event)
        handler.start()
        return QCoreApplication.exec_()
    def event(self, e):
        if e.type() == QEvent.KeyPress :
            print "key: %d" % e.key()
            return True
        else:
            print "Other QEvent type" 
        return super(EventHandlerApp, self).event(e)

if __name__ == "__main__":
    import sys
    qApp = EventHandlerApp(sys.argv)
    sys.exit(qApp.exec_())




Enjoy!
--
Emmanuel

On 21:58 Tue 10 May     , Benjamin wrote:
> 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
> _______________________________________________
> Qt-interest mailing list
> Qt-interest at qt.nokia.com
> http://lists.qt.nokia.com/mailman/listinfo/qt-interest

-- 
Emmanuel


More information about the PyQt mailing list