2017-02-20 10 views
0

I umgesetzt Beispiel (Kapitel 2) von "Mastering Qt 5" Buch, aber der Code stürzt ab, wenn Widget centralWidget Layout hinzufügen:SIGSEGV beim Hinzufügen von Widgets in Qt

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

Ich vermute, dass der centralWidget nicht das Layout hat Also stürzt es ab, aber ich weiß nicht, wie ich das beheben soll.

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

} 

Hier sind zwei weitere Klassen, die helfen könnten, das Problem zu lösen. Einige von euch könnten das Buch auch mit dem ganzen Code haben (daher habe ich es erwähnt).

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"); 
} 

Diese Klasse erstellt und setzt das Layout (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

Versuchen Sie, die Ausgabe für 'qDebug() << ui-> centralWidget' und für' qDebug() << ui-> centralWidget-> layout() 'vor der Absturzlinie zu sehen. Und insgesamt, außer vielleicht Hauptfenster, ist es keine gute Übung, UI-Widgets auf Stapel oder als ein Wert, der kein Zeigerelement in der Klasse ist, zu platzieren. Es ändert ihren Lebenszyklus nicht so, wie der Qt normalerweise handelt. Sie sollten lieber das Widget mit 'new MyWidget (this)' oder 'new MyWidget (someParent)' zuweisen. So ist es mehr wie Qt. – AlexanderVX

+0

@AlexanderVX Es ist nichts falsch, das Widget auf dem Stack als Mitglied einer Klasse zuzuweisen. Es kommt wirklich auf das Szenario an - müssen Sie das Widget zu einem bestimmten Zeitpunkt dynamisch löschen, bevor der Destruktor der Widget-Klasse, von der es Mitglied ist, zerstört wird. Solange Sie nicht vergessen, "delete" NICHT auf diesem Widget aufzurufen und es auch als Argument an verschiedene Funktionen zu übergeben, verwenden Sie '&' (zum Beispiel: 'connect (& this-> myWidgetOnStack, SIGNAL (...), ...) ') du bist gut zu gehen. – rbaleksandar

+0

@rbaleksandar Das war nicht der Hauptpunkt, aber Szenarien beim Zuordnen auf Stack ist nicht gut. Repariere das Widget zum Beispiel. Und parent funktioniert in beide Richtungen als die Instanz für die Veröffentlichung dieses untergeordneten Widgets und steuert auch das Verhalten nach Grad. Ich würde dem Anfänger nicht empfehlen, Widgets auf dem Stack oder nach dem Wert in der Klasse zu verwenden, obwohl es mangefähig ist. – AlexanderVX

Antwort

0

Wenn ich etwas im Code verpasst haben Sie zur Verfügung gestellt haben, haben Sie nicht wirklich Ihr zentrales Widget gesetzt. Standardmäßig ruft der Aufruf QMainWindow::centralWidget() einen Nullzeiger zurück. Sie müssen zuerst QMainWindow::setCentralWidget(QWidget* yourCentralWidget) anrufen, bevor Sie es anrufen. Und ja, Sie müssen auch ein Layout hinzufügen, wenn Sie layout()->addWidget(...) verwenden möchten. Sie können eine Instanz eines generischen QWidget erstellen, das Layout festlegen, ein zentrales Widget festlegen und dann damit arbeiten.

+0

Das war, was ich den Autor fragte, um sicher zu sein. – AlexanderVX

0

Sie Ihr Problem entweder durch Hinzufügen eines Layouts in C beheben ++:

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

oder im UI-Designer, indem diese Tasten: Layout buttons

Beachten Sie, dass aktiv für die Tasten sein, Sie müssen um mindestens ein Widget in Ihrem zentralen Widget zu haben und dann Ihr zentrales Widget auszuwählen. Anschließend können Sie schreiben:

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

Schließlich können Sie auch Ihre CpuWidget zur ui Datei bewegen Sie mit der „Förderung zu ...“ im Kontextmenü. In diesem Fall würden Sie nicht mCpuWidget benötigen, aber Sie könnten darauf mit etwas wie ui->cpuWidget zugreifen.

Für weitere Informationen lesen Sie die Qt Designer Handbuch:

+0

Vielen Dank für Ihr Feedback. Ich werde mir Zeit nehmen und alles verdauen. Fürs Erste habe ich ui-> centralWidget-> setLayout (new QVBoxLayout()) hinzugefügt; und es hat das Problem behoben. Ich habe versucht, den Fehler in UI Designer zu beheben, aber ich muss etwas falsch gemacht haben, da ich es nicht zum Laufen bringen konnte. Ich war verwirrt, was in der SysInfoWidget-Klasse getan wurde (Einstellung des Layouts mit QVBoxLayout). Ich hätte das in MainWindow machen sollen, aber ich vermute, dass das Layout nur auf SysInfoWidget angewendet wurde. Im MainWindow brauchte ich noch ein anderes. – Mira

1

Ich bin der Co-Autor des Buches "Mastering Qt 5"!

Ich denke, Ihr Verdacht über das Layout korrekt ist:

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

Ohne Layout definiert die zurückgegebenen Artikel null ist so können Sie nicht die Methode Layout() aufrufen.

Wenn Sie einige Fehler beim Erlernen haben Sie zum letzten Quellcode gehostet auf GitHub hier beziehen sollten: https://github.com/PacktPublishing/Mastering-Qt-5

Werfen Sie einen Blick auf die Datei „Mastering-Qt-5/Chapter_02/MainWindow.ui“:

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

Wie Sie kann für dieses Projekt sehen, horizontalLayout des Typs QHBoxLayout ist in der centralWidget definiert.

  1. Rechtsklick auf ‚MainWindow.ui‘ in der Projekthierarchie Ansicht
  2. Wählen Sie „Öffnen-mit: Sie können ganz einfach eine„.ui“Datei mit einem Texteditor von Qt Creator mit den folgenden Schritten bearbeiten "
  3. Schließlich "Plain-Text-Editor"

Wählen Sie "Formulareditor", wenn Sie zurück in den WYSIWYG-Editor kommen wollen.

Wie in anderen Antworten vorgeschlagen, wie es von C++ mit der folgenden Zeile zu tun, ist auch richtig:

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

Danke hier den Mangel an Informationen über das Layout für die Hervorhebung. Ich habe eine issue erstellt, um eine Errata zu diesem Thema hinzuzufügen.

Verwandte Themen