piro1107
@piro1107
Студент

Почему если вызывать QWidget::show() через точку, то не показывает?

Допустим есть у меня класс MyWidget и унаследован он от QWidget. Создаю единственный мой рукодельный виджет my. Помещаю в него кнопку. При нажатии на неё отсылается сигнал в my. Там в это время стоит слот, который принимает отосланный сигнал и в ответ создаёт QWidget и показывает его как отдельный элемент.

Описание класса:
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();

public slots:
    void show_widget( void )
    {
        QWidget w;

        QLineEdit *line = new QLineEdit;

        QVBoxLayout *vertical = new QVBoxLayout;
        vertical->addWidget(line);

        w.setLayout(vertical);
        w.setGeometry(100, 100, 300, 200);
        w.show();
    }
};

#endif // WIDGET_H


И мейн:
#include <QApplication>
#include <QtGui>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;

    QPushButton *btn = new QPushButton("Show widget");
    QObject::connect(btn, SIGNAL(clicked()),
                     &w, SLOT(show_widget()));

    QHBoxLayout *buttons = new QHBoxLayout;
    buttons->addWidget(btn);

    w.setLayout(buttons);
    w.setGeometry(200, 100, 800, 500);
    w.show();

    return a.exec();
}


Я на это дело ожидаю, что при клике всплывёт окошко, но не тут то было. Но достаточно мне заменить точку на стрелочку и, разумеется, объект на указатель на объект и (о чудо!) всё работает:

void Widget::show_widget( void )
{
    QWidget *w = new QWidget;

    QLineEdit *line = new QLineEdit;

    QVBoxLayout *vertical = new QVBoxLayout;
    vertical->addWidget(line);

    w->setLayout(vertical);
    w->setGeometry(100, 100, 300, 200);
    w->show();
}


Чисто академический вопрос: почему так?
  • Вопрос задан
  • 3270 просмотров
Решения вопроса 2
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
достаточно мне заменить точку на стрелочку и, разумеется, объект на указатель на объект и (о чудо!) всё работает

Самого главного не сказал: "и объект QWidget на стеке текущей функции на объект в куче".

Чисто академический вопрос: почему так?

Потому что в первом случае виджет разрушается при выходе из функции show_widget, а во втором остаётся болтаться в куче. Выход происходит сразу после возврата из QWidget::show, а сам этот вызов неблокирующий.
Ответ написан
bogolt
@bogolt
Вам уже ответили правильно, хочу добавить что в Qt все окна и контролы нужно создавать в куче ( так как тогда сама Qt сможет корректно их удалить ). Кроме того при создании нового объекта не забывайте указать ему на его родителя ( в вашем случае при создании QWidget внутри класса Widget -
QWidget* w = new QWidget(this);
QLineEdit *line = new QLineEdit(w);
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы