Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ Qt GUI _ Две формы !

Автор: maxvanceffer 9.6.2009, 19:26

Подскажите почему так происходит :

Вообщем после того как первая форма делает всё что нужно должна отобразиться вторая (её я добавил через креатор, то есть он сам там все инклуды прописал) я делаю примерно следующее

void Splash::vsioOK(){
   MainDialog w;
   w.show();
}


И после того как отрабатывает эта функция второе окно на секунду появляться её края и она тут же исчезает а винда подаёт звук что действие не может быть выполнена .

Ребять кто знает почему она не отображаться?

Автор: Litkevich Yuriy 9.6.2009, 19:40

после выхода из функции объект перестанет существовать
это С++

Автор: maxvanceffer 9.6.2009, 23:11

Да уж представляю как смеялись когда отвечали ....
Да уж не подскажите где его объявлять лучше что доступ был с первой формы.

Автор: Litkevich Yuriy 9.6.2009, 23:27

maxvanceffer, если это диалог, который должен блокировать основное окно приложения, для ввода неких данных, то см. примеры в QDialog.

Если самостоятельное окно, то объяви указатель в родительском классе, а окно создавай оператором new

Автор: igor_bogomolov 9.6.2009, 23:29

Цитата(maxvanceffer @ 10.6.2009, 0:11) *
Да уж представляю как смеялись когда отвечали ....
Достаточно распространеная ошибка, так что никто не смеялся.

В классе Splash, создай указатель на класс MainWindow
MainWindow *w;
В конструкторе, обнули этот указатель.

Твой метод переделываем след. образом
void Splash::vsioOK(){
    if(!w) {
        w = new MainDialog(this);
        connect(); \\соединяешь нужные сигналы со слотами
    }
    w->show();
    w->activateWindow();
}

Автор: maxvanceffer 10.6.2009, 12:16

А вот тут возник такой вопрос. Вот в первой форме набралось много нужных функции для второго окна. И чтоб не переписывать их все а наследовать или как виртуальными как это можно сделать ?

Автор: maxvanceffer 13.6.2009, 5:40

Вот я сделал всё по совету igor_bogomolov через указатели.

А как теперь получить обратный доступ к первой форме ? В частности её событию show();

Автор: Litkevich Yuriy 13.6.2009, 10:27

Цитата(maxvanceffer @ 13.6.2009, 9:40) *
А как теперь получить обратный доступ к первой форме ? В частности её событию show();
А зачем тебе обратный доступ от ребёнка к родителю?

Автор: maxvanceffer 13.6.2009, 20:31

Просто первая прячится при открывании второй, что не плодить окон одной программы. Да и пользователь будет больше всего времени находиться в первом окне. Вот и нужно назад показать главную форму. Помогите плиз как это сделать.

Автор: Litkevich Yuriy 13.6.2009, 21:27

Если ты передаёшь во второе окно указатель на первое, то этим указателем и воспользуйся (вызови метод show())

Автор: maxvanceffer 13.6.2009, 21:43

А можно маленикй пример ... А что то туго как то доходит.

Вот пример :
это в классе первого окна обьява
Second *window;
в реализации первого класса :
window=new Second(this);

а вот во втором классе как к этому обратиться через this?

Автор: Litkevich Yuriy 13.6.2009, 22:06

Цитата(maxvanceffer @ 14.6.2009, 1:43) *
window=new Second(this);

а вот во втором классе как к этому обратиться через this?
покажи объявление второго класса

Автор: maxvanceffer 13.6.2009, 22:13

Раскрывающийся текст
namespace Ui {
class SettingDialog;
}

class SettingDialog : public QDialog {
Q_OBJECT
Q_DISABLE_COPY(SettingDialog)
public:
explicit SettingDialog(QWidget *parent = 0);
virtual ~SettingDialog();
void initVars(QString SettingFile);

protected:
virtual void changeEvent(QEvent *e);

private:
Ui::SettingDialog *m_ui;
void startup();
int Changes;
QString Settings;
QMessageBox *mes;

private slots:
void on_exitButton_clicked();
void on_autoLoginCheckBox_stateChanged(int );
void on_popupCheckBox_stateChanged(int );
void on_saveButton_clicked();

signals:
void closeEvent();
};

Автор: BRE 13.6.2009, 22:18

Цитата(maxvanceffer @ 13.6.2009, 22:43) *
А можно маленикй пример ... А что то туго как то доходит.

Вот пример :
это в классе первого окна обьява
Second *window;
в реализации первого класса :
window=new Second(this);

а вот во втором классе как к этому обратиться через this?

Если я правильно понял вопрос, то ты хочешь из Second получить доступ к родительскому окну?
void Second::method()
{
    First *wnd = qobject_cast<First*>( parent() );
    Q_ASSERT( wnd != 0 );
    wnd->method();
}

Автор: Litkevich Yuriy 13.6.2009, 22:39

1) Один вариант тебе написал BRE.
2) Второй вариант, как и первый, только убрать приведение типа, и вызывать метод show (приведение не нужно т.к. это родной метод QWidget)

Т.к. у тебя второе окно наследник от QDialog, то могут быть ещё два варианта:
3) Перед вызовом твоего диалога, соедени его сигнал void finished ( int result ) со слотом show первого окна.

4) А может стоит пользоваться модальным диалогом? Я сильно сомневаюсь, что основное окно будет мешать пользователю. А вот исчезновение главного окна а потом появление, т.е мелькание окон, явно его выведет из равновесия.

Цитата(maxvanceffer @ 14.6.2009, 2:13) *
signals:
void closeEvent();
вот это зря. с таким именем, хоть и с другой сигнатурой, уже есть функция у базового класса (QWidget). Лучше придумай другое имя.

Автор: BRE 13.6.2009, 22:45

Цитата(Litkevich Yuriy @ 13.6.2009, 23:39) *
2) Второй вариант, как и первый, только убрать приведение типа, и вызывать метод show (приведение не нужно т.к. это родной метод QWidget)

Метод parent описан в QObject и соответственно возвращает указатель на QObject. Приведение типа все равно нужно, правда приводить можно к QWidget.

Цитата
QObject * QObject::parent () const

Автор: maxvanceffer 13.6.2009, 23:26

Ура всем спосибо получилась по примеру BRE , пытался соединять раньше сигна со слотом из главного в ребёнка но не срабатывала. Но по совету BRE получилось !!! Еще поиграюсь сразными возожнастями .... щас читаю статейку об этом....

Автор: Litkevich Yuriy 14.6.2009, 0:22

Цитата(BRE @ 14.6.2009, 2:45) *
Метод parent описан в QObject и соответственно возвращает указатель на QObject.
Пардон, я недосказал:
Я имел в виду указатель на родителя parent, передаваемый в конструктор, вместо метода parent()
explicit SettingDialog(QWidget *parent = 0);
см. код maxvanceffer в 13 сообщении. Но, как я и говорил - это способ для данного конкретного случая. У BRE - универсальный.

Автор: SABROG 14.6.2009, 12:44

Цитата(BRE @ 13.6.2009, 23:18) *
Если я правильно понял вопрос, то ты хочешь из Second получить доступ к родительскому окну?
void Second::method()
{
    First *wnd = qobject_cast<First*>( parent() );
    Q_ASSERT( wnd != 0 );
    wnd->method();
}


Q_ASSERT ничего не пишет в консоль при release сборке, в любом случае программа продолжит своё выполнение и выпадет по AV. Кстати достаточно написать так Q_ASSERT(wnd);, но в любом случае это только лишь warning в debug сборке.

Автор: BRE 14.6.2009, 13:06

Цитата(SABROG @ 14.6.2009, 13:44) *
Q_ASSERT ничего не пишет в консоль при release сборке, в любом случае программа продолжит своё выполнение и выпадет по AV.

Она и не должна ничего писать в релизе, такие ошибки должны выявляться на этапе отладки.

Цитата(SABROG @ 14.6.2009, 13:44) *
Кстати достаточно написать так Q_ASSERT(wnd);

Свой код я так и пишу, никогда не делаю сравнение с 0. Либо if( wnd ), либо if( !wnd ). Но это вопросы стиля написания, у каждого свои предпочтения. ;)

Цитата(SABROG @ 14.6.2009, 13:44) *
но в любом случае это только лишь warning в debug сборке.

Это варнинг и abort.

Автор: SABROG 14.6.2009, 14:01

Цитата(BRE @ 14.6.2009, 14:06) *
Она и не должна ничего писать в релизе, такие ошибки должны выявляться на этапе отладки.

С точки зрения оптимизации понимаю, не надо сравнивать каждый раз через if. Но вот воссоздать ситуацию на этапе отладки зачастую сложная штука.

Цитата(BRE @ 14.6.2009, 14:06) *
Это варнинг и abort.


К сожалению только в debug сборке. В релизе это ни варнинга ни аборта, а через 9 месяцев ребеночек появится :)

Автор: BRE 14.6.2009, 14:06

Цитата(SABROG @ 14.6.2009, 15:01) *
Но вот воссоздать ситуацию на этапе отладки зачастую сложная штука.

Это как? Программа - это абсолютно строгая последовательность действий. Ни каких случайностей там быть не должно... ;)

Цитата(SABROG @ 14.6.2009, 15:01) *
К сожалению только в debug сборке. В релизе это ни варнинга ни аборта, а через 9 месяцев ребеночек появится :)

К радости! Зачем мне тянуть в релиз код, который по умолчанию никогда не выполниться? И assert'ы как раз для таких проверок и придумались.

Автор: SABROG 14.6.2009, 14:34

Цитата(BRE @ 14.6.2009, 15:06) *
Это как? Программа - это абсолютно строгая последовательность действий. Ни каких случайностей там быть не должно... ;)

Шутник :) Я о том, что некоторые баги проявляются при разных стечениях обстоятельств, разные ОС, разные компьютеры, битые винты, плохая связь на линии, злой антивирус. Причем хуже всего, когда указатель каким-то макаром становится псевдо-валидным, к нему можно обращаться, работать как с объектом, а вот в его членах данных мусор.

Цитата(BRE @ 14.6.2009, 15:06) *
К радости! Зачем мне тянуть в релиз код, который по умолчанию никогда не выполниться? И assert'ы как раз для таких проверок и придумались.


Мне кажется тут не та же ситуация. Одно дело, когда данные должны быть в обязательном порядке валидные и совсем другое - parent(). У объекта может и не быть родителя, т.е. тут двойственная ситуация, которая не означает, что программа работает не правильно.

С другой стороны дальнейшая работа приложения врятли будет корректной. Хотя, если это какой-нибудь не критичный участок типа дополнительного функционала в программе, которым пользователи могут и не пользоваться никогда, то зачем закрывать программу? У нас на работе в программе есть функции, которые заведомо не работают и постоянно выдают AV (программа на Delphi), но она прекрасно продолжает работать и мы не пользуемся этими функциями, чтобы не получать лишние варнинги.

Автор: BRE 14.6.2009, 14:54

Цитата(SABROG @ 14.6.2009, 15:34) *
Шутник :) Я о том, что некоторые баги проявляются при разных стечениях обстоятельств, разные ОС, разные компьютеры, битые винты, плохая связь на линии, злой антивирус. Причем хуже всего, когда указатель каким-то макаром становится псевдо-валидным, к нему можно обращаться, работать как с объектом, а вот в его членах данных мусор.

Если происходят такие чудеса, то где гарантия, что использование проверки if( wnd ) вместо assert исправит ситуацию.... :)
Но я все равно уверен, что в грамотно написанной программе никаких случайностей быть не может.
Если человек пишить
QObject *parenObj;
QWidget *wnd = new QWidget( parentObj );

и этот код работает в debug и сыпется в release, то это проблемы самого человека (его кода).

Цитата(SABROG @ 14.6.2009, 15:34) *
Мне кажется тут не та же ситуация. Одно дело, когда данные должны быть в обязательном порядке валидные и совсем другое - parent(). У объекта может и не быть родителя, т.е. тут двойственная ситуация, которая не означает, что программа работает не правильно.

Вот именно в этой ситуации использование assert оправдано. Во время разработки программист может забыть указать родителя или по ошибке в качестве парента будет указан объект другого класса. Во время отладочного запуска ему тут-же датут по рукам и он все исправит. После отладки данная проверка уже не нужна, мы уверены что парент тот который надо.
Еще бывают ситуации, когда по логике работы программы объекты могут быть разными или их может не быть вообще, вот тогда нужно добавлять проверки, которые будут жить и работать всегда. НО только если это предусмотренно самой программой!

Цитата(SABROG @ 14.6.2009, 15:34) *
С другой стороны дальнейшая работа приложения врятли будет корректной. Хотя, если это какой-нибудь не критичный участок типа дополнительного функционала в программе, которым пользователи могут и не пользоваться никогда, то зачем закрывать программу? У нас на работе в программе есть функции, которые заведомо не работают и постоянно выдают AV (программа на Delphi), но она прекрасно продолжает работать и мы не пользуемся этими функциями, чтобы не получать лишние варнинги.

Если кусок программы не работает, то может более гуманно вставить заглушку с выводом сообщения типа "Куда ты тыкаешь, эта функция не реализована!". :)

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)