在学习QThread和QProcess的时候,想做一个类似多线程进程监测的工具,写demo的时候遇到了几个问题,网上搜索到的方法均无法解决,望大佬答疑
QProcess: Destroyed while process ("cmd.exe") is still running.
QWinEventNotifier: Event notifiers cannot be enabled or disabled from another thread
错误: 无法终止 PID 为 18668 的进程。
原因: 只能强行终止这个进程(带 /F 选项)。
下方是我的代码
程序界面及组件名称
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "processmonitor.h"
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
ProcessMonitor *pm;
void setupConnection();
private slots:
void handleReadyReadStandardOutput(const QString& data);
void handleReadyReadStandardError(const QString& data);
void handleStarted(const QString& message);
void handleStateChanged(QProcess::ProcessState newState);
void handleStopped(const QString& message);
void on_start_process_clicked();
void on_stop_process_clicked();
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "./ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), pm(new ProcessMonitor)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
if(!pm) {
qDebug() << "ProcessMonitor Start Failed,Exit!";
QApplication::quit();
}
setupConnection();
}
MainWindow::~MainWindow()
{
if(pm) {
pm->stopProcess();
delete pm;
}
delete ui;
}
void MainWindow::setupConnection() {
connect(pm, &ProcessMonitor::readyReadStandardOutput, this, &MainWindow::handleReadyReadStandardOutput);
connect(pm, &ProcessMonitor::readyReadStandardError, this, &MainWindow::handleReadyReadStandardError);
connect(pm, &ProcessMonitor::started, this, &MainWindow::handleStarted);
connect(pm, &ProcessMonitor::stateChanged, this, &MainWindow::handleStateChanged);
connect(pm, &ProcessMonitor::stopped, this, &MainWindow::handleStopped);
}
void MainWindow::handleReadyReadStandardOutput(const QString& data){
this->ui->outInfo->appendPlainText(data);
}
void MainWindow::handleReadyReadStandardError(const QString& data){
this->ui->outInfo->appendPlainText("Error:" + data );
}
void MainWindow::handleStarted(const QString& message){
this->ui->selfInfo->appendPlainText(message);
}
void MainWindow::handleStateChanged(QProcess::ProcessState newState) {
QString stateString;
switch(newState) {
case QProcess::NotRunning:
stateString = "Not Running";
break;
case QProcess::Starting:
stateString = "Starting";
break;
case QProcess::Running:
stateString = "Running";
break;
default:
stateString = "Unknown State";
break;
}
this->ui->selfInfo->appendPlainText("State Changed: " + stateString);
}
void MainWindow::handleStopped(const QString& message){
this->ui->selfInfo->appendPlainText(message);
}
void MainWindow::on_start_process_clicked()
{
this->pm->start();
}
void MainWindow::on_stop_process_clicked()
{
this->pm->stopProcess();
}
processmonitor.h
#ifndef PROCESSMONITOR_H
#define PROCESSMONITOR_H
#include <QThread>
#include <QProcess>
#include <QDebug>
class ProcessMonitor : public QThread
{
Q_OBJECT
public:
ProcessMonitor();
~ProcessMonitor();
void run() override;
void stopProcess();
signals:
void readyReadStandardOutput(QString output);
void readyReadStandardError(QString error);
void started(QString message);
void stateChanged(QProcess::ProcessState newState);
void stopped(QString message);
private:
QProcess *process;
private slots:
void handleReadyReadStandardOutput();
void handleReadyReadStandardError();
void handleStarted();
void handleStateChanged(QProcess::ProcessState newState);
};
#endif // PROCESSMONITOR_H
processmonitor.cpp
#include "processmonitor.h"
ProcessMonitor::ProcessMonitor()
: process(nullptr)
{
}
ProcessMonitor::~ProcessMonitor() {
stopProcess(); // 确保在销毁时停止进程
}
void ProcessMonitor::run() {
if (this->process) {
delete this->process;
}
this->process = new QProcess();
if (!this->process) {
qDebug() << "Error: unable to instantiate QProcess";
return;
}
// this->process->setWorkingDirectory("E:\\test");
connect(this->process, &QProcess::readyReadStandardOutput, this, &ProcessMonitor::handleReadyReadStandardOutput);
connect(this->process, &QProcess::readyReadStandardError, this, &ProcessMonitor::handleReadyReadStandardError); // 修正此处
connect(this->process, &QProcess::started, this, &ProcessMonitor::handleStarted);
connect(this->process, &QProcess::stateChanged, this, &ProcessMonitor::handleStateChanged);
this->process->start("cmd.exe");
qDebug() << "ProcessID:" << this->process->processId();
this->exec();
}
void ProcessMonitor::stopProcess() {
if (!this->process) {
emit stopped("[ProcessMonitor] No Process Created");
return; // 直接返回
}
this->process->terminate();
// this->process->kill();
if (this->process->waitForFinished(3000)) {
emit stopped("[ProcessMonitor] Process Stopped");
} else {
this->process->kill();
emit stopped("[ProcessMonitor] Process terminated failed, Killing");
}
delete this->process; // 安全检查后直接释放内存
this->process = nullptr; // 置空指针
this->quit(); // 确保在退出前永远调用
}
void ProcessMonitor::handleReadyReadStandardOutput() {
if (!this->process) return;
QByteArray data = this->process->readAllStandardOutput();
emit readyReadStandardOutput(QString::fromLocal8Bit(data));
}
void ProcessMonitor::handleReadyReadStandardError() {
if (!this->process) return;
QByteArray data = this->process->readAllStandardError();
emit readyReadStandardError(QString::fromLocal8Bit(data));
}
void ProcessMonitor::handleStarted() {
emit started("[ProcessMonitor] Process Started");
}
void ProcessMonitor::handleStateChanged(QProcess::ProcessState newState) {
emit stateChanged(newState);
}
相似问题