c++ - Mac 上的 Qt:app.exec() 阻止终端输入,如何重写这个最小示例?
问题描述
我已经阅读了很多关于此的内容,但我不完全了解如何去做(例如,请参阅如何避免 Qt app.exec() 阻塞主线程)。
下面的代码是我想要实现的一个非常简单的最小示例。对于这个例子:有一个终端,您可以在其中为一个学生输入同一科目的考试成绩。具体来说:学生全年的英语课程表现如何。每次输入学生的成绩时,Qt 图表都会更新并显示进度。
这是我写的代码:
#include <iostream>
#include <vector>
#include <QApplication>
#include <QMainWindow>
#include <QChartView>
#include <QLineSeries>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
std::vector<int> examScores;
int totalExams = 5;
QtCharts::QLineSeries *series = new QtCharts::QLineSeries();
QtCharts::QChart *chart = new QtCharts::QChart();
chart->legend()->hide();
chart->createDefaultAxes();
QtCharts::QChartView *chartView = new QtCharts::QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);
QMainWindow window;
window.setCentralWidget(chartView);
window.resize(400, 300);
for (int i = 1; i <= totalExams; i++)
{
std::cout << "Enter score of exam " << i << " ";
std::string userInput;
getline(std::cin, userInput);
int score = std::stoi(userInput);
examScores.push_back(score);
series->append(i, score);
chart->addSeries(series);
window.show();
app.exec();
chart->removeSeries(series);
}
return 0;
}
现在,从软件工程的角度来看,这里有很多问题(例如不清理输入等),但我无法解决的是如何重写app.exec();
. 我知道它不应该存在,因为它是阻塞的,而且我知道 Qt 不应该以这种方式编写。
所以我想知道:您将如何重写此示例以实现app.exec();
非阻塞并允许程序始终在终端上接收用户输入?
解决方案
这就是我如何将它放入自己的线程,同时仍然能够处理 CLI 输入。从代码审查的角度来看,这段代码仍然有很多问题,但基本功能(将其放入不同的线程)是有效的。
#include <iostream>
#include <vector>
#include <thread>
#include <QApplication>
#include <QMainWindow>
#include <QChartView>
#include <QLineSeries>
std::vector<int> examScores;
void pollForUserInput(QtCharts::QLineSeries *series, int totalExams)
{
for (int i = 1; i <= totalExams; i++)
{
std::cout << "\nEnter score of exam " << i << " " << std::endl;
std::string userInput;
getline(std::cin, userInput);
int score = std::stoi(userInput);
examScores.push_back(score);
series->append(i, score);
}
std::cout << "done" << std::endl;
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QtCharts::QLineSeries *series = new QtCharts::QLineSeries();
int totalExams = 5;
std::thread t1(pollForUserInput, series, totalExams);
QtCharts::QChart *chart = new QtCharts::QChart();
chart->legend()->hide();
chart->addSeries(series);
chart->createDefaultAxes();
chart->axisX()->setRange(1, totalExams); // see https://stackoverflow.com/questions/38804179/how-to-repaint-a-qchart
chart->axisY()->setRange(1, 10); // see https://stackoverflow.com/questions/38804179/how-to-repaint-a-qchart
QtCharts::QChartView *chartView = new QtCharts::QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);
QMainWindow window;
window.setCentralWidget(chartView);
window.resize(400, 300);
window.show();
return app.exec();
}
推荐阅读
- bash - 如何使用 Bash 在 Jupyter Notebook 中打印单元格的内容
- reactjs - 多次调用useReducer的dispatcher,需要同步
- python - pandas 遍历列以查找文本匹配,一旦找到,比较两个数据帧中的相邻行值 <>
- android - 为什么我在使用 android studio 时会收到此错误。?
- javascript - 关于全局变量和全局范围的术语问题
- macos - Big Sur 大纲视图可扩展项目损坏
- javascript - 尝试使用特定日期的值获取第一个元素的标题
- c# - 显示链接时,集合视图中的项目未与 MVVM 一起显示
- arrays - 我无法理解 Python 中的递归或迭代动态循环
- python - 你如何清除内存使用情况?