我有一个程序运行适合于某些数据的最小二乘方。此过程在单独的线程中运行,并通过对话框进行控制。该对话框有一个QPlainTextEdit,显示适合的更新和最终报告。QPlainTextEdit扔std :: bad_alloc
该对话框是在Qt Designer中创建的,代码运行到QtCreator中,我的Qt版本是4.8.1。
我遇到的问题有些不稳定。当我第一次运行程序时,一切都很好。然后,如果我再次运行它,有时程序与消息
崩溃终止叫做抛出“的std :: bad_alloc的” 的实例以后有什么()的std :: bad_alloc的 该方案已完成意外。
我将问题追踪到调用QPlainTextEdit的clear()方法。这是一些代码。
// Snippets of the class definition
class QLSQDialog : public QDialog, public Ui_QLSQDialog
{
Q_OBJECT
public:
QLSQDialog(QWidget *parent = 0);
(...)
void UpdateDisplay(const QString &msg, int iter, double norm); // Update values of chi, etc on displays
signals:
void Run(); // Signal to run a LSQ procedure
(...)
private slots:
void on_btnRun_clicked();
(...)
private:
void Enables(bool running); // Enable and disable features depending on running state of LSQ fit
(...)
};
// Snippets of the class implementation
QLSQDialog::QLSQDialog(QWidget *parent) : QDialog(parent)
{
setupUi(this); // Set up dialog
(...)
txtInfo->clear(); // txtInfo is a QPlainTextEdit created in Designer
(...)
}
void QLSQDialog::UpdateDisplay(const QString &msg, int iter, double norm)
{
lblChi->setText(QString::number(norm,'f',12));
if (iter >= 0) lblIt->setText(QString::number(iter));
txtInfo->appendPlainText(msg);
}
void QLSQDialog::on_btnRun_clicked()
{
txtInfo->clear(); // Offending line in second run
Enables(true);
emit Run();
}
void QLSQDialog::Enables(bool running)
{
bool Idle = !running;
bool HasReport = !txtInfo->document()->isEmpty();
(...)
btnReport->setEnabled(Idle && HasReport);
}
txtInfo
是QPlainTextEdit对象。当创建对象 以显示空文本编辑时,我会调用txtInfo->clear()
。当我点击'运行'工具按钮时,它的默认插槽会发出一个运行信号,以启动新线程。在这个线程中更新了txtInfo
QPlainTextEdit,直到完成(实际上线程发出一个信号,该信号在主应用程序中被捕获,然后调用UpdateDisplay
)。
如果我第二次点击运行按钮,那么我得到崩溃和错误。如果我替换txtInfo->clear()
,txtInfo->document()->clear()
,txtInfo->setPlainText("")
或txtInfo->document()->setPlainText("")
,则问题是相同的(第二次执行时崩溃)。有时候,但不是很频繁,我可以在碰撞之前运行几次(10次左右)。
最后,如果我注释掉txtInfo->clear()
这一行,那么我可以像我试过的那样运行例程(在一次测试中,我运行约80次后感到很疲倦)。
我唯一的(几乎是随机的)猜测是这个问题与某个线程的更新有关(它会发出一个被捕获的信号,然后调用UpdateDisplay
函数)。我这么认为的原因是,如果我将信号注释掉,并创建一个新的按钮来调用带有一些虚假信息的UpdateDisplay
,那么一切都很好。
A qApp->processEvents()
在违规行不起作用之前。
我被困在这里。任何想法都欢迎。例如,我可以做任何测试来验证调用clear()
方法是否正常?
你可能不应该从线程调用'QWidget'方法。他们不是线程安全的。你需要发出信号给主要的gui线程来查看,并通过调用方法直接回应。 – jdi 2012-08-11 19:10:19
事实上,你是对的,我确实遇到过麻烦。我的描述有点短。我有一个在线程中运行的工作对象。它用更新参数发出一个信号。该信号被主应用程序捕获,该应用程序又调用UpdateDisplay。我编辑了这个问题来指出这一点。 – rpsml 2012-08-11 19:55:58