QT 进程在 SLOT 中命中时会自动终止
Posted
技术标签:
【中文标题】QT 进程在 SLOT 中命中时会自动终止【英文标题】:QT Process gets killed automatically when it hits in SLOT 【发布时间】:2017-02-20 12:14:35 【问题描述】:我编写了一个 QT 代码,它在单击按钮时启动一个新进程,该进程必须执行一个 shell 脚本并根据脚本结果动态地将 Std 输出/错误附加到文本浏览器上。代码在自定义插槽中失败。这就是我的 window.h 是什么
class Window : public QWidget
Q_OBJECT
public:
explicit Window(QWidget *parent = 0);
QPushButton *goButton;
QTextBrowser *statusWindow;
QProcess *process;
private slots:
void go_Button_Clicked();
void updateOutput();
;
这就是我的 window.cpp 的样子
Window::Window(QWidget *parent) : QWidget(parent)
// Text Browser
statusWindow = new QTextBrowser(this);
// Create the Go button, make "this" the parent
goButton = new QPushButton(this);
connect(goButton, SIGNAL (clicked()), this, SLOT (go_Button_Clicked()));
void Window::go_Button_Clicked()
// Step1 - Create a new process
QProcess *process = new QProcess(this);
// Step2 - Connect the Signals and slot
qDebug() << connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(updateOutput()));
// Step3 - Start the Script process
process->start("/home/root/script.sh");
qDebug() << "Process in main";
void Window::updateOutput()
qDebug() << "Process in update Output";
//statusWindow->append(process->readAllStandardOutput());
所以每当我在更新输出中取消注释行时,只要我点击按钮,GUI 就会崩溃。使用 qdebug 我设法发现 GUI 崩溃 bcoz 行“statusWindow->append(process->readAllStandardOutput());” .
如果注释了该行,则调试消息会继续在控制台上打印,但使用未注释的行,我会收到一次调试消息,然后 GUI 崩溃。这是调试输出。
true
true
Process in main
Process in update Output
Process killed by signal
知道这里发生了什么,我熟悉 QT 中的调试
【问题讨论】:
@G.M 这是我错过在这里添加代码的一个错误,它与 Go 按钮一起出现。您可以查看更新后的帖子 【参考方案1】:替换:
QProcess *process = new QProcess(this);
通过
process = new QProcess(this);
您正在使用未初始化的成员变量进程,因为在Window::go_Button_Clicked()
中您正在创建一个局部变量。
编辑
实际上,代码很容易出错。当用户多次按下按钮时会发生什么。然后在插槽中,您可能会读取错误进程的输出。 一种解决方法可能是:您根本不将 QProcess 定义为成员,而是像现在一样将其定义为局部变量。然后在槽中,您可以将发送者转换为 QProcess*,除非它失败,否则使用此实例。它将永远是正确的。之后,不要忘记删除发件人。为此使用 deleteLater()。
【讨论】:
当他第二次点击按钮时,他会得到内存泄漏。 @Evgeny 改进建议正在路上:-)【参考方案2】:在您的 void Window::go_Button_Clicked()
插槽中,您隐藏在 .h
文件中声明的带有新变量的 QProcess *process
QProcess *process = new QProcess(this);
将此行替换为
process = new QProcess(this);
但是当您第二次单击时,您会出现内存泄漏,并且无法从第一个进程中获取更多数据。所以你应该以某种方式改变你的设计。
【讨论】:
以上是关于QT 进程在 SLOT 中命中时会自动终止的主要内容,如果未能解决你的问题,请参考以下文章