У меня есть класс прослушивателя входа QT, который сигнализирует stdin
входы в работающем QCoreApplication
.Я хочу использовать это как в Windows, так и в Linux.
Мой текущий подход заключается в использовании #ifdef Q_OS_WIN
внутри обоих заголовков и cpp для выполнения кода, специфичного для платформы.Как я знаю, что #ifdef
считается вредным, и его следует избегать, я хочу реорганизовать его таким образом, чтобы у меня был один единственный заголовочный файл inputlistener.h
и позволить системе сборки выбирать между определенными windows/inputlistener.cpp
или linux/inputlistener.cpp
Может быть, с дополнительным inputlistener_global.cpp
, который содержит код, который не зависит от платформы.
Однако я не могу найти решение, как убрать #ifdef
в заголовке.
Как мне этого добиться?
Вот мой нынешний подход:
#inputlistener.h
#ifndef INPUTLISTENER_H
#define INPUTLISTENER_H
#include <QtCore>
class inputlistener : public QObject {
Q_OBJECT
private:
#ifdef Q_OS_WIN
QWinEventNotifier* m_notifier;
#else
QSocketNotifier* m_notifier;
#endif
signals:
void inputeventhappened(int keycode);
private slots:
void readyRead();
public:
inputlistener();
};
#endif // INPUTLISTENER_H
#inputlistener.cpp
#include "inputlistener.h"
#include "curses.h"
#ifdef Q_OS_WIN
#include <windows.h>
#endif
inputlistener::inputlistener()
{
#ifdef Q_OS_WIN
m_notifier = new QWinEventNotifier(GetStdHandle(STD_INPUT_HANDLE));
connect(m_notifier, &QWinEventNotifier::activated
#else
m_notifier = new QSocketNotifier(0, QSocketNotifier::Read, this);
connect(m_notifier, &QSocketNotifier::activated
#endif
,
this, &inputlistener::readyRead);
readyRead(); // data might be already available without notification
}
void inputlistener::readyRead()
{
// It's OK to call this with no data available to be read.
int c;
while ((c = getch()) != ERR) {
emit inputeventhappened(c);
}
}