[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