在Qt中添加小部件时的SIGSEGV

时间:2017-02-20 20:06:49

标签: qt

我在"掌握Qt 5"中实施了示例(第2章)。预订,但在将小部件添加到centralWidget的布局时,代码崩溃了:

ui->centralWidget->layout()->addWidget(&mCpuWidget)

我怀疑centralWidget没有布局,因此它崩溃但我不知道如何解决这个问题?

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
mCpuWidget(this)
{
    ui->setupUi(this);
    SysInfo::instance().init();
    ui->centralWidget->layout()->addWidget(&mCpuWidget);

}

这里还有两个类可能有助于找出问题所在。你们中的一些人也可能拥有所有代码的书(因此我提到了它)。

CpuWidget::CpuWidget(QWidget* parent):
SysInfoWidget(parent),
mSeries (new QPieSeries (this))
{
    mSeries->setHoleSize(0.35);
    mSeries->append("CPU Load", 30.0);
    mSeries->append("CPU Free", 70.0);

    QChart* chart = chartView().chart();
    chart->addSeries(mSeries);
    chart->setTitle("CPU Average Load");
}

此类创建并设置布局(QVBoxLayout)

    SysInfoWidget::SysInfoWidget(QWidget *parent, int startDelayMs, int updateSeriesDelayMs) :
    QWidget(parent),
    mChartView(this)

{
    mRefreshTimer.setInterval(updateSeriesDelayMs);
    connect(&mRefreshTimer, &QTimer::timeout,
            this, &SysInfoWidget::updateSeries);

    QTimer::singleShot(startDelayMs,
                       [this] {mRefreshTimer.start();});

    mChartView.setRenderHint(QPainter::Antialiasing);
    mChartView.chart()->legend()->setVisible(false);

    QVBoxLayout* layout = new QVBoxLayout(this);
    layout->addWidget(&mChartView);
    setLayout(layout);
}

3 个答案:

答案 0 :(得分:2)

我是“Mastering Qt 5”一书的合着者!

我猜您对布局的怀疑是正确的:

ui->centralWidget->layout()->addWidget(&mCpuWidget);

如果没有定义任何布局,则返回的项目为 null ,因此您无法调用方法布局()。

如果您在学习过程中遇到一些错误,请参阅github上托管的最终源代码:https://github.com/PacktPublishing/Mastering-Qt-5

查看文件“Mastering-Qt-5/Chapter_02/MainWindow.ui”:

<ui version="4.0">
  ...
  <widget class="QWidget" name="centralWidget">
   <layout class="QHBoxLayout" name="horizontalLayout"/>
  </widget>
 ...
</ui>

正如您在此项目中看到的那样,在 centralWidget 中定义了QHBoxLayout类型的 horizo​​ntalLayout 。您可以使用Qt Creator中的文本编辑器轻松编辑“.ui”文件,步骤如下:

  1. 右键单击“项目层次结构视图”中的“MainWindow.ui”
  2. 选择“打开方式”
  3. 最后是“纯文本编辑器”
  4. 如果要返回WYSIWYG编辑器,请选择“表单编辑器”。

    正如其他答案中所建议的那样,使用以下行从C ++中执行此操作的方法也是正确的:

    ui->centralWidget->setLayout(new QHBoxLayout());
    

    感谢您在此强调缺乏有关布局的信息。我创建了一个issue来添加关于此主题的勘误表。

答案 1 :(得分:0)

除非我在您提供的代码中遗漏了某些内容,否则您实际上并未设置中央窗口小部件。默认情况下,调用QMainWindow::centralWidget()会返回NULL指针。在打电话之前,您需要先致电QMainWindow::setCentralWidget(QWidget* yourCentralWidget)。是的,如果您想使用layout()->addWidget(...),还需要为其添加布局。您可以创建泛型QWidget的实例,设置其布局,设置为中央窗口小部件,然后使用它。

答案 2 :(得分:0)

您可以通过在C ++中添加布局来解决您的问题:

ui->setupUi(this);
SysInfo::instance().init();
ui->centralWidget->setLayout(new QVBoxLayout()); // Or any other layout class
ui->centralWidget->layout()->addWidget(&mCpuWidget);

或者在UI Designer中使用这些按钮: Layout buttons

请注意,要激活按钮,您需要在中央窗口小部件中至少包含一个窗口小部件,然后选择中央窗口小部件。然后你可以写:

ui->setupUi(this);
SysInfo::instance().init();
// One way
ui->centralWidget->layout()->addWidget(&mCpuWidget);
// Another way
ui->layout->addWidget(&mCpuWidget);

最后,您还可以使用上下文菜单中的“提升为...”选项将CpuWidget移动到ui文件。在这种情况下,您不需要mCpuWidget,但可以使用ui->cpuWidget之类的内容访问它。

欲了解更多信息,请阅读Qt Designer手册: