首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Qt中添加小部件时的SIGSEGV

在Qt中添加小部件时的SIGSEGV
EN

Stack Overflow用户
提问于 2017-02-21 04:06:49
回答 3查看 1K关注 0票数 0

我实现了“精通Qt 5”一书中的示例(第2章),但在将小部件添加到centralWidget的布局中时,代码崩溃:

代码语言:javascript
复制
ui->centralWidget->layout()->addWidget(&mCpuWidget)

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

代码语言:javascript
复制
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
mCpuWidget(this)
{
    ui->setupUi(this);
    SysInfo::instance().init();
    ui->centralWidget->layout()->addWidget(&mCpuWidget);

}

下面是另外两个类,它们可能有助于解决这个问题。你们中的一些人可能也有这本书,里面有所有的代码(因此我提到了它)。

代码语言:javascript
复制
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)

代码语言:javascript
复制
    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);
}
EN

回答 3

Stack Overflow用户

发布于 2017-06-29 18:44:50

我是"Mastering Qt 5“这本书的合著者!

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

代码语言:javascript
复制
ui->centralWidget->layout()->addWidget(&mCpuWidget);

如果没有定义任何布局,则返回的项为、空、,因此不能调用方法()。

如果你在学习过程中遇到一些错误,你应该参考github上的最终源代码:https://github.com/PacktPublishing/Mastering-Qt-5

看一看文件"Mastering-Qt-5/Chapter_02/MainWindow.ui":

代码语言:javascript
复制
<ui version="4.0">
  ...
  <widget class="QWidget" name="centralWidget">
   <layout class="QHBoxLayout" name="horizontalLayout"/>
  </widget>
 ...
</ui>

正如您在此项目中看到的,QHBoxLayout类型的horizontalLayout是在centralWidget中定义的。通过以下步骤,您可以使用Qt Creator中的文本编辑器轻松编辑".ui“文件:

  1. 在项目层次结构视图中右键单击"MainWindow.ui“
  2. 选择"Open-With"
  3. Finally”纯文本编辑器“

当你想返回所见即所得编辑器时,选择“表单编辑器”。

正如在其他答案中所建议的,在C++中使用下面这行代码来完成此操作的方法也是正确的:

代码语言:javascript
复制
ui->centralWidget->setLayout(new QHBoxLayout());

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

票数 2
EN

Stack Overflow用户

发布于 2017-02-21 05:22:06

除非我在您提供的代码中遗漏了什么,否则您实际上还没有设置您的中央小部件。默认情况下,调用QMainWindow::centralWidget()会返回一个空指针。在调用QMainWindow::setCentralWidget(QWidget* yourCentralWidget)之前,您需要先调用它。是的,如果你想使用layout()->addWidget(...),你还需要给它添加一个布局。您可以创建一个通用QWidget的实例,设置它的布局,set是一个中心小部件,然后使用它。

票数 0
EN

Stack Overflow用户

发布于 2017-02-21 21:47:43

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

代码语言:javascript
复制
ui->setupUi(this);
SysInfo::instance().init();
ui->centralWidget->setLayout(new QVBoxLayout()); // Or any other layout class
ui->centralWidget->layout()->addWidget(&mCpuWidget);

或在UI设计器中使用这些按钮:

请注意,要使按钮处于活动状态,您需要在中心小部件中至少有一个小部件,然后选择中心小部件。然后,您可以编写:

代码语言:javascript
复制
ui->setupUi(this);
SysInfo::instance().init();
// One way
ui->centralWidget->layout()->addWidget(&mCpuWidget);
// Another way
ui->layout->addWidget(&mCpuWidget);

最后,您还可以使用"Promote to...“将CpuWidget移动到ui文件中。选项。在这种情况下,您不需要mCpuWidget,但可以使用ui->cpuWidget之类的命令访问它。

有关更多信息,请阅读Qt Designer手册:

  • Using Layouts in Qt Designer
  • Using Custom Widgets with Qt Designer
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42353352

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档