[ fromfile: qprocess.xml id: qonsole2 ]
In the preceding example, Qonsole
had a separate widget for user input.
For a more authentic console experience, the user should be able to type commands directly in the command output window.
To accomplish this Qonsole
needs to capture keyboard events.
The first step is to override the the QObject base class eventFilter()
method, as shown in Example 17.10, the revised class definition.
Example 17.10. src/qonsole/keyevents/qonsole.h
[ . . . . ] class Qonsole : public QMainWindow { Q_OBJECT public: Qonsole(); public slots: void execute(); void showOutput(); bool eventFilter(QObject *o, QEvent *e) ; protected: void updateCursor(); private: QString m_UserInput; QTextEdit* m_Logw; QProcess* m_Shell; }; [ . . . . ]
<include src="src/qonsole/keyevents/qonsole.h" href="src/qonsole/keyevents/qonsole.h" id="qonsole2h" allfiles="1" mode="cpp"/>
As discussed in Section 8.3, an event is an object derived from QEvent.
Within the context of an application, such a QEvent is associated with a QObject that is its intended receiver.
The receiving object has a handler to process the event.
An eventFilter examines a QEvent and determines whether to permit it to be processed by the intended receiver.
We have provided our revised Qonsole
application with an eventFilter()
function that can be used to filter keyboard events from m_Logw
, an extended QTextEdit.
Qonsole
, an extended QMainWindow, is the intended recipient of those events.
The implementation of this function is shown in Example 17.11
Example 17.11. src/qonsole/keyevents/qonsole.cpp
[ . . . . ] bool Qonsole::eventFilter(QObject* o, QEvent* e) { if (e->type() == QEvent::KeyPress) { QKeyEvent* k = static_cast<QKeyEvent*> (e); int key = k->key(); QString str = k->text(); m_UserInput.append(str); updateCursor(); if ((key == Qt::Key_Return) || (key == Qt::Key_Enter) ) { #ifdef Q_WS_WIN m_UserInput.append(QChar(0x000A)); #endif execute(); return true; } else { m_Logw->insertPlainText(str); return true; } } return false; }
<include src="src/qonsole/keyevents/qonsole.cpp" mode="cpp" href="src/qonsole/keyevents/qonsole.cpp" id="eventfilter" segid="event"/>
When the Enter key is pressed, the member function execute()
is called so that the command string can be sent to the shell and then reset.
Example 17.12 shows the implementation of these two functions.
Example 17.12. src/qonsole/keyevents/qonsole.cpp
[ . . . . ] void Qonsole::updateCursor() { QTextCursor cur = m_Logw->textCursor(); cur.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); m_Logw->setTextCursor(cur); } void Qonsole::execute() { QByteArray bytes = m_UserInput.toUtf8(); m_Shell->write(bytes); m_UserInput = ""; }
<include src="src/qonsole/keyevents/qonsole.cpp" mode="cpp" href="src/qonsole/keyevents/qonsole.cpp" id="update-execute" segid="update-execute"/>
All that remains to be done is to call the base class function installEventFilter()
on m_Logw
, the widget whose events you want to capture.
This is done in the constructor, as shown in Example 17.13.
Example 17.13. src/qonsole/keyevents/qonsole.cpp
[ . . . . ] Qonsole::Qonsole() { m_Logw = new QTextEdit; setCentralWidget(m_Logw); m_Logw->installEventFilter(this); m_Logw->setLineWrapMode(QTextEdit::WidgetWidth); m_Shell = new QProcess(); m_Shell->setReadChannelMode(QProcess::MergedChannels); connect (m_Shell, SIGNAL(readyReadStandardOutput()), this, SLOT(showOutput())); #ifdef Q_WS_WIN m_Shell->start("cmd", QStringList(), QIODevice::ReadWrite); #else m_Shell->start("bash", QStringList("-i"), QIODevice::ReadWrite); #endif }
<include src="src/qonsole/keyevents/qonsole.cpp" mode="cpp" href="src/qonsole/keyevents/qonsole.cpp" id="q2ctr" segid="constructor"/>
Generated: 2012-03-02 | © 2012 Alan Ezust and Paul Ezust. |