Russian Qt Forum
Ноябрь 24, 2024, 15:37 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Помогите новичку. Как сделать приложение с >= 2 формами  (Прочитано 10819 раз)
okvorb
Гость
« : Май 16, 2007, 20:54 »

По форуму искал, книжку прочитал (QT. профессиональное программирование на с++). Но нигде не нашёл ответа как сделать приложение с гнесколькими формами ичтобы они взаимодействавали.

Есть прога (курсач. работа с БД). GUI делался в QT Designer'е. Приложение прекрасно работает с одной формой (Form1), как это и было задумано изначально. Но надо ещё добавить один диалог(Form2), который будет отображаться самым первым после запуска программы. В нём можно будет выбрать некоторые настройки, а дальше должно появится основное окно, а Form2 исчезнуть. Вот как это сделать ума не приложу ... Много лет назад делфи как-то юзал ... так там когда создаётся ещё одна форма , то можно было её добавить в проект или как-то связать с уже существующей .. чтобы она была вида в пространстве имён. Попробовал создать в дизайнере форму и потом добавить #include "form2.h" в main.cpp , но из этого ничего не вышло ... Помогите пожалуйста.


Версия QT: 3.3.8
ОС: Ubuntu GNU/Linux 7.04

Заранее огромное спасибо.
Записан
SABROG
Гость
« Ответ #1 : Май 16, 2007, 21:09 »

Вот мой каркас, вроде все работает.
//header
Код:

#ifndef FRSELECT_H
#define FRSELECT_H

#include <QMainWindow>
#include <QtGui>
#include "ui_frSelectForm.h"
#include "../include/TForm.h"
class cfrSelectForm : public QDialog, public Ui::frSelectForm // Ui::... - выдираю из исходников сгенерированных после компиляции .ui файла
{
    Q_OBJECT

public:
    cfrSelectForm(QWidget *parent = 0);

protected:
public slots:

protected:

private:
TForm *main; // указатель на класс моего наследника QMainWindow (главного окна)
};
#endif


//source
Код:

#include <QtGui>
#include "../include/TForm.h"
#include "../include/frSelectForm.h"

cfrSelectForm::cfrSelectForm(QWidget *parent): QDialog(parent, Qt::Sheet)
{
    main = (TForm *)parent;
    setupUi(this);
    main->setWindowTitle("test"); // проверяю, для теста устанавливаю заголовок главной формы
}


//main

Код:

#include <QtGui>
#include "../include/TForm.h"
#include "../include/frSelectForm.h"
void TForm::addFreight()
{

    cfrSelectForm selectFreight(this); // метод создает нашу модальную форму
    selectFreight.exec();
}
Записан
Sergeich
Гость
« Ответ #2 : Май 16, 2007, 21:36 »

2 SABROG:
Цитировать
Qt 3.3.8
 Веселый
Записан
Emc
Гость
« Ответ #3 : Май 16, 2007, 21:48 »

SABROG: гыгы все хорошо только версия qt3.3.8

>>чтобы она была вида в пространстве имён
-- не понял, что ты имеешь в виду
если нужно чтобы запускалась форма (Form2), а по ее закрытию Form1
то
1) обычным образом в main.cpp запускаешь Form2
2) в описание класса Form2 добавляешь
#include "form1.h"
и скажем такой код
Код:

void Form2::done(int r)
{
   Form1* f = new Form1(параметры);
   f.exec();
}
Записан
okvorb
Гость
« Ответ #4 : Май 16, 2007, 23:53 »

Цитата: "Emc"
SABROG: гыгы все хорошо только версия qt3.3.8

>>чтобы она была вида в пространстве имён
-- не понял, что ты имеешь в виду
если нужно чтобы запускалась форма (Form2), а по ее закрытию Form1
то
1) обычным образом в main.cpp запускаешь Form2
2) в описание класса Form2 добавляешь
#include "form1.h"
и скажем такой код
Код:

void Form2::done(int r)
{
   Form1* f = new Form1(параметры);
   f.exec();
}



Во блин ... всё оказалось проще простого.
Надо было просто кликнуть на Project Overview , а потом File -> New ->Dialog. После этого появлется в проекте Form2, а в ,main.cpp пишется Form2 f2; f2.show() и всё валит ! Всем спасибо.
Записан
okvorb
Гость
« Ответ #5 : Май 20, 2007, 11:41 »

Всё равно проблемы есть ...

в main.cpp обявил объект класса Form2. Это форма, которая стартует первой.

Код:

Form2 f2;
f2.show();


В файле form2.ui.h есть функциия, смысл который - подсоединиться к базе данных, спрятать Form2 (т.е. f2.hide() ) и показать Form1 (т.е. f1.show() ). Но компилятор сказал, что f2 не обявлена в этом участве и т.д. Оно и ясно .. f2 обяъвлена только в main.cpp. А как сделать так, чтобы f2 стала видна и в form2.ui.h ? В приниципе проблема такая, что где первый раз были объвлена объекты классов Form1 и Form2, там они видны и остаются, а если надо в приложении из разных мест (файлов) управляться с этими объектами, то тогда как нужно поступить ?

Код:

void Form2::fileSQLiteOpen()
{
    QString path = QFileDialog::getOpenFileName("");
    lineEdit17->setText(path); // имя файла базы
    connDB* dbConnect; // соединение с базой
    dbConnect -> connect(); // соединяемся
    Form1 f1; // f1 - главная форма  программы
    f1.show(); //показываем её
    //а форма f2 всё ещё на экране позади f1 и спрятать её не получается.
}


Я думал, что надо сделать хидер, где создаются объекты на обе формы, а потом его инкледить туда, где нужно использовать формы. Но не вышло ....

сделал myForms.h :

Код:

#ifndef _myForms_h_
#define _myForms_h_


#include "form1.h"
#include "form2.h"

Form1 f1;
Form2 f2;

#endif


подключил этот хидер в 2-х местах программы, а компилятор выдал ошибку :

.obj/form2.o:(.bss+0x0): multiple definition of `f1'
.obj/main.o:(.bss+0x0): first defined here
.obj/form2.o:(.bss+0x220): multiple definition of `f2'
.obj/main.o:(.bss+0x220): first defined here
collect2: выполнение ld завершилось с кодом возврата 1
make: *** [qELib] Ошибка 1


Очевидно, что я делаю какую-то бурду похоже ... получается что мой myForms.h создаёт в двух местах одни и те же объекты, поэтому компилятор и ругается, но я не могу понять как мне из разных мест (файлов) программы работать с объектами, которые были созданы в другом месте ... Извините за тупость.
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #6 : Май 20, 2007, 12:06 »

А покажи текст "form1.h" и  "form2.h". Очевидно у тебя они не окружены ифдефами:

Код:
#ifndef _FORM1_H_
#define _FORM1_H_

class Form1
{
...
};

#endif

#ifndef _FORM2_H_
#define _FORM2_H_

class Form2
{
...
};

#endif
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
okvorb
Гость
« Ответ #7 : Май 20, 2007, 13:09 »

Цитата: "pastor"
А покажи текст "form1.h" и  "form2.h". Очевидно у тебя они не окружены ифдефами:

Код:
#ifndef _FORM1_H_
#define _FORM1_H_

class Form1
{
...
};

#endif

#ifndef _FORM2_H_
#define _FORM2_H_

class Form2
{
...
};

#endif


хм ... так у меня нету этих файлов. я в Qt-Designer'е всё делаю ..  там только form1.ui.h  и form2.ui.h есть ... ну + main.cpp
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #8 : Май 20, 2007, 13:40 »

Ты в своём предыдущем посте указал именно "form1.h" и "form2.h". Ты имел ввиду form1.ui.h и form2.ui.h? И зачем тебе нужен myForms.h? Создавай объекты в main.cpp в функции main
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
okvorb
Гость
« Ответ #9 : Май 20, 2007, 13:56 »

Цитата: "pastor"
Ты в своём предыдущем посте указал именно "form1.h" и "form2.h". Ты имел ввиду form1.ui.h и form2.ui.h? И зачем тебе нужен myForms.h? Создавай объекты в main.cpp в функции main


Когда я добавил новую форму в проект, то в фпайле main.cpp астоматически появилась запись #include "form1.h". myForms.h я уже удалил из-за непригодности, но всё равно лажа ...

у меня в main.cpp обяъвлено :

Form2 f2;
f2.show();
всё работает, всё появляется.

из form2.ui.h мне надо запустить форму1:

Form1 f1;
f1.show();
всё работает.

из form2.ui.h мне надо после f1.show(), спрятать форму2. я делаю:

Form2* f2;
f2->hide() (пробовал и close() )
всё компилиться и работает, но форма2 не прячется ... почему ?
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #10 : Май 20, 2007, 14:26 »

Значит что -то делаешь не так. Выложи по возможности полный текст своей проги
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
okvorb
Гость
« Ответ #11 : Май 20, 2007, 21:53 »

Цитата: "pastor"
Значит что -то делаешь не так. Выложи по возможности полный текст своей проги


Да вот ... кроме form1.ui.h - там нету ничего связаного с работой форм.


main.cpp
Код:

#include <qapplication.h>
#include "form1.h"
#include "form2.h"


int main( int argc, char ** argv )
{
 
    QApplication a( argc, argv );
    Form2 f2;
    f2.show();
    a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) );
    return a.exec();
}



form2.ui.h
Код:

#include <qfiledialog.h>
#include <qstringlist.h>
#include <qsqldatabase.h>
#include <qstring.h>
#include "form1.h"
#include "connDB.h"





void Form2::SQLiteFile()
{
    lineEdit16->setText( QFileDialog::getOpenFileName() );
    connDB* db;
    db->connect();
    Form1 f1;
    Form2* f2;
    f1.exec();
    f2->hide();
   
}
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #12 : Май 21, 2007, 00:14 »

Непонятны вот эти строки:

Код:
Form2* f2;
f2->hide();

connDB* db;
db->connect();


f2, db указывают на неизвестную область памяти. Что-то здесь ты напутал. На этих строках прога может упасть.

Походу у тебя классы, покрайней мере Form1, наследован от QDialog. При вызове exec() у тебя показываеться диалог и блокироеться дальнейшее выполнение программы, до момента закрытия этого диалога. Т.е. строка f2->hide(); выполниться только после его закрытия.

Попробуй так:

Код:
void Form2::SQLiteFile() 
{
    lineEdit16->setText( QFileDialog::getOpenFileName() );
    //connDB* db;
    //db->connect();
    Form1 *f1 = new Form1(this);
    f1->show();
    hide();
}
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
okvorb
Гость
« Ответ #13 : Май 21, 2007, 00:52 »

Цитата: "pastor"
Непонятны вот эти строки:

Код:
Form2* f2;
f2->hide();

connDB* db;
db->connect();


f2, db указывают на неизвестную область памяти. Что-то здесь ты напутал. На этих строках прога может упасть.

Походу у тебя классы, покрайней мере Form1, наследован от QDialog. При вызове exec() у тебя показываеться диалог и блокироеться дальнейшее выполнение программы, до момента закрытия этого диалога. Т.е. строка f2->hide(); выполниться только после его закрытия.

Попробуй так:

Код:
void Form2::SQLiteFile() 
{
    lineEdit16->setText( QFileDialog::getOpenFileName() );
    //connDB* db;
    //db->connect();
    Form1 *f1 = new Form1(this);
    f1->show();
    hide();
}


ТОЧНО!!!!! Блин ну я морозил. ТОлько c connDB* db всё в порядке , это объект на класс, который выполняет подключение/отключение к базе. Он работает нормально и определен в connDB.h, который у меня подключается в form2.ui.h. А вот с f2 прямо в яблочку. прога, кстати и падала в кору ... теперь такой код работает на отлично :

Код:
void Form2::SQLiteFile() 
{
    lineEdit16->setText( QFileDialog::getOpenFileName() );
    connDB* db;
    db->connect();
    hide();
    Form1 *f1 = new Form1(this);
    f1->show();

}




Спасибище!!!!
Записан
Mikhail
Программист
*****
Offline Offline

Сообщений: 587


Просмотр профиля
« Ответ #14 : Май 21, 2007, 07:28 »

Падала она у тебя на
Цитировать

Form2* f2;
f2->hide();

в функции void Form2::SQLiteFile()

В данном случае f2 это неинициализированный локальный указатель.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.061 секунд. Запросов: 23.