QMainWindow and setCentralWidget: Don't delete Widget/Object (Similar method)



  • Hi

    When I add a QTextEdit with setCentralWidget to my MainWindow,the main window takes ownership and the widget is deleted from my current instance.This behaviour is very annoying for me. QTabWidget or QStackWidget just complicate my design (Because I want to use a QList for my subclassed QTextEdit -> direct pointer and currentWidget() of QTabWidget is not a real option). Is there a similar method to setCentralWidget without this deleting ? I need to maximizes the QTextEdit on the main frame, replace it with another QTextEdit (There are 10 QTextEdit's) and I want to access it with the pointer I have (directly).

    Thank you



  • To prevent the MainWindow from deleting your current central widget whenever you swap it for another widget, set the parent of the current central widget to 0.

    @
    QTextEdit newTextEdit = new QTextEdit;
    if (mainWindow->centralWidget())
    mainWindow->centralWidget()->setParent(0); // Preserve current central widget
    mainWindow->setCentralWidget(newTextEdit);
    @



  • Hi

    I am a bit confused. My Class Name is "MainWindow", the name of my central widget is centralWidget2 (Because centralWidget is a method of QMainWindow, but the default name of my central widget was centralWidget) (Qt Designer and ui_xyz File). My test code looks like this

    @#include "mainwindow.h"

    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
    {
    setupUi(this);

    test1 = new QTextEdit();
    test1->setPlainText("1");
    test2 = new QTextEdit();
    test2->setPlainText("2");

    status = false;
    setCentralWidget(test1);

    connect(actionCall, SIGNAL(triggered()), this, SLOT(foobar()));
    }

    MainWindow::~MainWindow()
    {

    }

    void MainWindow::foobar()
    {
    if(centralWidget())
    {
    centralWidget2->setParent(0);
    }
    if(status == false)
    {
    setCentralWidget(test2);
    status = true;
    }
    else
    {
    setCentralWidget(test1);
    status = false;
    }
    }
    @

    And the header file:
    @
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>
    #include <QTextEdit>
    #include "ui_mainwindow.h"

    class MainWindow : public QMainWindow, private Ui_MainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    QTextEdit *test1;
    QTextEdit *test2;
    bool status;

    public slots:
    void foobar();

    private:
    Ui::MainWindow *ui;
    };

    #endif // MAINWINDOW_H
    @

    But the program crashes after the first call of foobar()



  • Hi,

    @
    if(centralWidget())
    {
    centralWidget2->setParent(0);
    }
    @

    your variable centralWidget2 is never intialized, that's why your program is crashing. Instead, try:

    @
    if(centralWidget())
    {
    centralWidget()->setParent(0);
    }
    @



  • Hi

    Yes of course, I renamed it from "centralWidget" to "centralWidget2", because I had the following compiler errors:

    http://pastebin.com/B2m0HkXa

    Now my first widget on the QMainWindow has the name "centralWidget" (as default name by Qt Designer)
    Code (I have again the compiler errors):

    @
    #include "IDE.h"
    #include "ui_IDE.h"

    IDE::IDE(QWidget *parent) : QMainWindow(parent)
    {
    setupUi(this);

    test1 = new QTextEdit(this);
    test1->setText("1");

    test2 = new QTextEdit(this);
    test2->setText("2");

    setCentralWidget(test1);
    status = false;
    }

    IDE::~IDE()
    {

    }

    void IDE::foobar()
    {
    if(centralWidget())
    {
    centralWidget()->setParent(0);
    }
    if(status == false)
    {
    setCentralWidget(test2);
    status = true;
    }
    else
    {
    setCentralWidget(test1);
    status = false;
    }
    }
    @

    Header:

    @
    #ifndef IDE_H
    #define IDE_H

    #include <QMainWindow>
    #include <QTextEdit>
    #include "ui_IDE.h"

    class IDE : public QMainWindow, private Ui_IDE
    {
    Q_OBJECT

    public:
    explicit IDE(QWidget *parent = 0);
    ~IDE();

    private:
    Ui::IDE *ui;
    QTextEdit *test1;
    QTextEdit *test2;
    bool status;

    private slots:
    void foobar();
    };

    #endif // IDE_H
    @



  • Why don't you want to use a QStackedWidget again?



  • This is a longer story. I want to use some files. Each file should have an own instance (QTextEdit to display and some internal variables).

    I was unsure what is better:

    • Subclass this file class from QWidget (Then I can use it with a QTabWidget -> Best way)
    • Subclass this file class from QTextEdit (Then I can use it with a QStackWidget -> Okay)
    • Write a standalone class with a QWidget, return this widget and use it as a layout-widget in the base class

    The first solution is the best, but not that clean as the third ;)



  • So you basically want to show a main window with a tabbed interface. Am I right?

    That's actually quite easy, because a QTabWidget can be used to display any kind of QWidget subclass, be it QTextEdit or a subclass of it.

    @
    class FileEdit : public QTextEdit // or any other class that is or
    // directly or indirectly inherits QWidget
    {
    ...
    bool internalVariable;
    }

    class MainWindow : public QMainWindow
    {
    public:
    MainWindow()
    {
    tabWidget_ = new QTabWidget;

        tabWidget_->addTab(new FileEdit, QStringLiteral("File 1"));
        tabWidget_->addTab(new FileEdit, QStringLiteral("File 2"));
        ...
    
        setCentralWidget(tabWidget_);
    }
    

    private:
    QTabWidget *tabWidget_;
    }
    @
    Brain to terminal.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.