拥有基于 Qt 和 ncurses 的应用程序,在等待用户输入时每秒刷新屏幕的最佳方法是什么? (例如显示时钟并获取用户输入)。
我需要 CPU 使用率和应用程序响应能力之间的最佳折衷。
更具体地说,如何获取用户输入并仍然使用QTimer
以及信号槽机制?
使用下面的代码时,计时器不起作用。
nodelay(stdscr,true); while(1) { sleep(1); getch(); processInput(); }
Use QSocketNotifier
收到可用信息的通知stdin
.
呼叫非阻塞getch()
循环直到没有更多输入可用。这一点非常重要:通知者只有在以下情况下才会通知new数据可用,但这并不意味着它会通知每个字符!如果您一次收到多个字符,您通常只会收到一个通知 - 因此您必须继续发出非阻塞通知getch()
直到它返回ERR
这意味着目前没有更多数据可用。
您还应该读取在连接套接字通知程序之前可用的所有数据。
The code below echoes the input as it receives it, and additionally outputs a *
every second. This works on Linux and OS X, and is not portable to Windows. To quit, press Q.
Using ncurses对于传统的文本模式用户界面(如果需要),同时利用 Qt 处理其他一切(计时、网络、具有基于文本的视图的数据模型、XML、QObjects 等)是一种完全有效的方法。
// https://github.com/KubaO/stackoverflown/tree/master/questions/ncurses-20606318
#include <QtCore>
#include <ncurses.h>
class Worker : public QObject
{
Q_OBJECT
QSocketNotifier m_notifier{0, QSocketNotifier::Read, this};
QBasicTimer m_timer;
Q_SLOT void readyRead() {
// It's OK to call this with no data available to be read.
int c;
while ((c = getch()) != ERR) {
printw("%c", (char)(c <= 255 ? c : '?'));
if (c == 'q' || c == 'Q') qApp->quit();
}
}
void timerEvent(QTimerEvent * ev) {
if (ev->timerId() != m_timer.timerId()) return;
printw("*");
refresh();
}
public:
Worker(QObject * parent = 0) : QObject(parent) {
connect(&m_notifier, SIGNAL(activated(int)), SLOT(readyRead()));
readyRead(); // data might be already available without notification
m_timer.start(1000, this);
}
};
int main(int argc, char *argv[])
{
QCoreApplication a{argc, argv};
Worker w;
auto win = initscr();
clear();
cbreak(); // all input is available immediately
noecho(); // no echo
printw("Press <q> to quit\n");
keypad(win, true); // special keys are interpreted and returned as single int from getch()
nodelay(win, true); // getch() is a non-blocking call
auto rc = a.exec();
endwin();
return rc;
}
#include "main.moc"
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)