2017-02-20 133 views
0
添加窗口小部件時

我從「掌握的Qt 5」的書,但添加小部件centralWidget的佈局時,代碼崩潰實施例(第2章):SIGSEGV Qt中

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); 
} 
+0

嘗試在碰撞線之前看到'qDebug()<< ui-> centralWidget'和'qDebug()<< ui-> centralWidget-> layout()'的輸出。總的來說,除了主窗口之外,將UI小部件放在堆棧上或作爲類中的非指針成員的值不是一個好習慣。它修改了它們的生命週期,而不是Qt通常處理的方式。您應該考慮使用'new MyWidget(this)'或'new MyWidget(someParent)'分配小部件。這樣它就更像是Qt。 – AlexanderVX

+0

@AlexanderVX作爲類的成員在堆棧上分配小部件沒有任何問題。這真的取決於場景 - 你需要在它的成員被銷燬的構件類的析構函數之前的某個時刻動態地刪除構件。只要你不忘記不要在這個小部件上調用'delete',並且使用'&'將它作爲參數傳遞給各種函數(例如:connect(&this-> myWidgetOnStack,SIGNAL(...) ...)''你很好走。 – rbaleksandar

+0

@rbaleksandar這並不是主要的觀點,但是在分配堆棧時出現的情況並不好。重新分配小部件,例如。並且父母以雙方的方式作爲釋放該孩子小部件的實例,並且還將行爲控制爲程度。我不會推薦新手在堆棧中使用小部件,或在課堂上使用價值,儘管它是可以管理的。 – AlexanderVX

回答

0

除非我已經錯過了你提供你有沒有實際設置您的中心插件的代碼的東西。默認情況下,調用QMainWindow::centralWidget()返回一個空指針。在打電話之前,您需要先致電QMainWindow::setCentralWidget(QWidget* yourCentralWidget)。是的,如果你想使用layout()->addWidget(...),你還需要添加一個佈局。您可以創建通用QWidget的實例,設置其佈局,設置爲中心小部件,然後使用它。

+0

這就是我要求作者確定的內容。 – AlexanderVX

0

您可以通過添加C++中的佈局解決您的問題:使用這些按鈕

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

還是在UI設計師: Layout buttons

注意的按鈕被激活,你需要在您的中央小部件中至少有1個小部件,然後選擇您的中央小部件。然後,你可以寫:

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設計手冊:

+0

謝謝大家的反饋。我會花時間消化所有這些。現在,我添加了ui-> centralWidget-> setLayout(new QVBoxLayout());並解決了問題。我嘗試在UI設計器中進行修復,但我一定做了錯誤的事情,因爲我無法使它工作。我對SysInfoWidget類的做法感到困惑(使用QVBoxLayout設置佈局)。我雖然這應該已經在MainWindow中完成,但我猜這個佈局只適用於SysInfoWidget ..我仍然需要在MainWindow中有不同的佈局。 – Mira

1

我的書 「Mastering Qt 5」 的合着者!

我猜你對佈局的懷疑是正確的:

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

沒有任何佈局定義返回的產品所以你不能調用該方法佈局()。

如果你有你的學習過程中,你應該是指託管在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> 

正如你可以看到對於這個項目,一個horizo​​ntalLayout的類型QHBoxLayout被定義在的中心部件中。您可以輕鬆編輯與Qt Creator的文本編輯器下面的步驟一「的.ui」文件:在項目層次視圖

  1. 的‘MainWindow.ui’右鍵單擊
  2. 選擇「開帶「
  3. 最後‘純文本編輯器’

選擇‘表格編輯器’,當你想回來的所見即所得的編輯器。

在其他的答案建議,從C與下面的行做++的方式也是正確的:

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

感謝您凸顯缺乏對這裏的佈局信息。我創建了一個issue來添加關於此主題的勘誤表。