Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Передача данных от одной формы другой
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt GUI
Страницы: 1, 2
neneTc
Здравствуйте! Столкнулся с проблемой при передаче данных от одной форме другой. Предлагали использовать сигналы-слоты, но формы не имеют указателя друг на друга чтобы через сигналы-слоты взаимодействовать. Как мне всё-таки сконнектить и осуществить передачу данных между двумя формами?
kwisp
neneTc,
Цитата(neneTc @ 9.3.2010, 17:02) *
формы не имеют указателя друг на друга

это не обязательно, соединять и разъединять можно в любом месте программы. хоть в main.cpp главное чтоб там указатели были.
neneTc
В main.cpp нет указателя на второе окно
kwisp
Цитата(neneTc @ 9.3.2010, 17:08) *
В main.cpp нет указателя на второе окно

ну я для примера сказал :)
где то же есть место где есть оба указателя на кона?

если нет создай его.(место)
neneTc
а как осуществить передачу через коннект?
kwisp
так
neneTc
Спасибо) После 3 дней втыкания в различные маны всё заработало! Наконец-то)
Vexar
Цитата(neneTc @ 10.3.2010, 1:16) *
Спасибо) После 3 дней втыкания в различные маны всё заработало! Наконец-то)


А можно подробнее что да как?
Litkevich Yuriy
Цитата(Vexar @ 19.3.2010, 6:55) *
А можно подробнее что да как?
что именно не понятно?
Vexar
Есть у меня Главное окно и Диалоговое. Мне нужно передать данные из Диалогового окна в Главное.

Делаю так:

Dialog:

    LoginSysName = new QLabel(tr("Name:"));
    LineEditName = new QLineEdit;
    LoginSysName->setBuddy(LineEditName);
    QObject::connect(LineEditName, SIGNAL(textChanged(QString)), LineEdit, SLOT(setText(QString)));


MainWindow:

    LineEdit = new QLineEdit;
    QObject::connect(LineEdit, SIGNAL(textChanged(QString)), LineEditName, SLOT(setText(QString)));
Litkevich Yuriy
Вопрос:
1) Диалоговое окно модальное?
Vexar
Диалоговое окно, но лучше наверно сделать модальное.

mainwindow.cpp

void MainWindow::LoginSys()
{
    if (!EnterDialog)
    {
         EnterDialog = new LoginSysDialog(this);
    }

    EnterDialog->show();
    EnterDialog->activateWindow();
}
Litkevich Yuriy
обычно данные из диалоговых окон передаются в главное, по закрытию диалогового окна.
Для этого в диалоговом окне предусматривают методы чтения данных.
Например, для чтения текста из LoginSysDialog::LineEditName, можно написать метод LoginSysDialog::name, тогда в главном окне после закрытия диалога просто вызываешь этот метод.
Вот у меня диалог ввода имени пользователя и пароля:
class DialogLogin : public QDialog, public Ui::DialogLogin
{
    Q_OBJECT
public:
    DialogLogin(QWidget* parent= 0);
    
    QString    login() const;
    QString    password() const;
};
Вот так используется в главном окне:
DialogLogin    loginDialog(this);

if (loginDialog.exec() == QDialog::Accepted)
{
    login=loginDialog.login();
    pswd=loginDialog.password();
}
PunX
Здравствуйте, я своём приложении мне необходимо сделать следующее: при запуске появляется окно где пользоветль вводит логин и пароль, после успешной авторизации появляется основное(главное) окно программы.
Я делаю следующее:
1. в Qt Creator создаю GUI приложение
2. добавляю в него новую форму и добавляю соответствующие этой форме файлы .h и .cpp
3. в файл .h добавляю следующее:
#ifndef DIALOG_LOGIN_H
#define DIALOG_LOGIN_H
#include <QDialog>

namespace Li {
    class MyForm;
}

class MyWidget: public QDialog
{
    Q_OBJECT
public:
    MyWidget(QDialog *parent = 0);
    ~MyWidget();

private:
    Li::MyWidget *li;
};
#endif // DIALOG_LOGIN_H

4. в файл .cpp добавляю
#include "dialog_login.h"
#include "ui_dialog_login.h"

MyWidget::MyWidget(QDialog *parent)
    :QDialog(parent), li(new Li::MyForm())
{
    li->setupUi(this);
}

MyWidget::~MyWidget()
{
    delete li;
}

Но даже на этом шаге компиляция рушиться с ошибками. Подскажите пожалуйста, на каком шаге делаю что-то не так?
BRE
А почему неймспейс называется Li::? По-умолчанию uic вроде генерирует Ui::
namespace Li {
    class MyForm;
}
PunX
Да, это исправил заменил на Ui, но это не помогло.
BRE
Цитата(PunX @ 8.4.2010, 20:20) *
Да, это исправил заменил на Ui, но это не помогло.

private:
    Ui::MyForm *li;
}
PunX
отредактировал до такого состояния, ошибок стало вроде меньше, но всё ранво не пойму что не так
.h
#ifndef DIALOG_LOGIN_H
#define DIALOG_LOGIN_H
#include <QDialog>
namespace Ui {
    class login;
}
class login : public QDialog{
    Q_OBJECT
public:
    login(QDialog *parent = 0);
    ~login();

private:
    Ui::login *ui;
};
#endif // DIALOG_LOGIN_H

.cpp
#include "dialog_login.h"
#include "ui_dialog_login.h"

login::login(QDialog *parent) : QDialog(parent),ui(new Ui::login)
{
    ui->setupUI(this);
}

login::~login()
{
    delete ui;
}
BRE
#include "dialog_login.h"
login::login(QDialog *parent) : QDialog(parent),ui(new Ui::login)
{
    ui->setupUi(this);
}


А лучше покажи сразу все ошибки. :)
PunX
project_alfa/dialog_login.cpp:4: error: invalid use of incomplete type 'struct Ui::login'
project_alfa/dialog_login.h:5: error: forward declaration of 'struct Ui::login'
project_alfa/dialog_login.cpp:6: error: invalid use of incomplete type 'struct Ui::login'
project_alfa/dialog_login.h:5: error: forward declaration of 'struct Ui::login'
project_alfa/dialog_login.cpp:10: warning: possible problem detected in invocation of delete operator:
project_alfa/dialog_login.cpp:10: warning: invalid use of incomplete type 'struct Ui::login'
project_alfa/dialog_login.h:5: warning: forward declaration of 'struct Ui::login'
project_alfa/dialog_login.cpp:10: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined.

вот все которые вылетают, может я свою задачу не так реализовываю? может можно проще всё сделать?
BRE
А точно в файле ui_dialog_login.h класс называется login?
С учетом регистра и т.д.?
PunX
Спасибо нашёл ошибку) надо было имя класса поменять на Dialog.
Litkevich Yuriy
Цитата(PunX @ 8.4.2010, 23:04) *
:QDialog(parent), li(new Li::MyForm())
в конструктор MyForm наверняка надо передать this и не удалять его руками в последствии
PunX
Сейчас формы вызываются, всё вроде работает. Перечитал все соообщения в теме сначала, но не понял как теперь связать эти две формы? как сделать чтобы при удачном завершении формы входа, открывалось основное окно? (Подозреваю что всё это делается с помощью slot-ов?)
PunX
Поставлю вопрос по другому, можно ли сделать так чтобы сначала запускалось окно входа (логин), при получении данных с него, открывалось главное окно, а окно логина закрывалось?
Litkevich Yuriy
Цитата(PunX @ 9.4.2010, 0:03) *
Подозреваю что всё это делается с помощью slot-ов?
нет. Я приводил пример в сообщении №13

Цитата(PunX @ 9.4.2010, 2:09) *
так чтобы сначала запускалось окно входа (логин), при получении данных с него, открывалось главное окно, а окно логина закрывалось?
тогда вызывай диалог до создания главного окна
PunX
Извините может за глупые вопросы, могли бы вы привести пример как вызвать диалог для создания главного окна?
Litkevich Yuriy
Цитата(PunX @ 9.4.2010, 2:17) *
как вызвать диалог для создания главного окна?
в функции main.
int main(int argc, char *argv[])
{

    QApplication app(argc, argv);
    
    QString login, password;
    const QString LOGIN = "mylogin", PASSWORD = "mypassword";
    {
        MyDialog dialog(this);
        if (dialog.exec() == QDialog::Rejected)
            return 1;
        if (dialog.login() != LOGIN) || (dialog.password() != PASSWORD)
            return 1;
    }
    MainWindow w;

    w.resize(750, 550);
    w.show();

    return app.exec();
}
PunX
Всё прекрасно работает и окно входа и потом запускается главное окно, НО появилась такая потребность получить в главное окно логин пользователя который был введён в окне входа. Способ из 13 сообщения этой темы не подходит, т.к. диалоговое окно входа (где вводится логин и пароль) вызывается в main.cpp и получить данные в других модулях не получается.
BRE
Можно передать их в конструкторе MainWindow:
int main(int argc, char *argv[])
{

    QApplication app(argc, argv);
    
    QString login, password;
    const QString LOGIN = "mylogin", PASSWORD = "mypassword";
    {
        MyDialog dialog(this);
        if (dialog.exec() == QDialog::Rejected)
            return 1;
        if (dialog.login() != LOGIN) || (dialog.password() != PASSWORD)
            return 1;
    }
    MainWindow w( login, password );

    w.resize(750, 550);
    w.show();

    return app.exec();
}
PunX
Вообщем у меня получилось такое
login.h
Раскрывающийся текст
#ifndef LOGIN_H
#define LOGIN_H
#include <QtSql>
#include "dialog_login.h"
#include <QMessageBox>
QString error;

bool createConnections(QString db_dbname,QString db_host,QString db_username,QString db_pass)
{

    QSqlDatabase psql = QSqlDatabase::addDatabase( "QPSQL" );
    if ( !psql.driver() ) {
        error = "Failed to connect to psql driver";
        return FALSE;
    }

    psql.setDatabaseName( db_dbname );
    psql.setUserName( db_username );
    psql.setPassword( db_pass );
    psql.setHostName( db_host );

    if ( !psql.open() ) {
        error = "Failed to open orders database: " +
                psql.lastError().driverText();
        error = psql.lastError().databaseText();
        psql.close();
        return FALSE;
    }
    return TRUE;
}
bool enter (){
    Dialog dialog;
    if(dialog.exec() == QDialog::Rejected)
        return 1;
    if(!createConnections("postgres","localhost",dialog.login(),dialog.password()))
    {
        int i = QMessageBox::warning(0,"Warning","incorrect password or username\n"+error,QMessageBox::Ok);
        if(i == QMessageBox::Ok){
            enter();
        }
        return 1;
    }else{
        return 0;
    }

}
#endif // LOGIN_H

и main.cpp
Раскрывающийся текст
#include <QtGui/QApplication>
#include <QMessageBox>
#include "mainwindow.h"
#include "dialog_login.h"
#include "login.h"
int main(int argc, char *argv[])
{
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Windows-1251"));    ///< Для строковых констант
    QTextCodec::setCodecForTr(QTextCodec::codecForName("Windows-1251"));        ///< Для функций перевода tr()
    QApplication a(argc, argv);
    if(enter()){
        return 0;
    }

    MainWindow w;
    w.show();
    return a.exec();
}

как сделать так чтобы db_username,db_dbname были доступны и эти переменные можно было использовать?
BRE
Цитата(PunX @ 11.4.2010, 21:32) *
как сделать так чтобы db_username,db_dbname были доступны и эти переменные можно было использовать?

Доступны где?
PunX
Доступны для того чтобы вывести их на форму, т.е. доступны в mainwindow.cpp.
BRE
Можно, например так:

main.cpp
Раскрывающийся текст
#include <QtGui/QApplication>
#include <QMessageBox>
#include "mainwindow.h"
#include "dialog_login.h"

bool createConnections(QString db_dbname,QString db_host,QString db_username,QString db_pass)
{

    QSqlDatabase psql = QSqlDatabase::addDatabase( "QPSQL" );
    if ( !psql.driver() ) {
        error = "Failed to connect to psql driver";
        return FALSE;
    }

    psql.setDatabaseName( db_dbname );
    psql.setUserName( db_username );
    psql.setPassword( db_pass );
    psql.setHostName( db_host );

    if ( !psql.open() ) {
        error = "Failed to open orders database: " +
                psql.lastError().driverText();
        error = psql.lastError().databaseText();
        psql.close();
        return FALSE;
    }
    return TRUE;
}

int main(int argc, char *argv[])
{
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Windows-1251"));    ///< Для строковых констант
    QTextCodec::setCodecForTr(QTextCodec::codecForName("Windows-1251"));        ///< Для функций перевода tr()
    QApplication a(argc, argv);

    QString db_name = "postgres";
    QString db_login;

    forever
    {
        Dialog dialog;
        if(dialog.exec() == QDialog::Rejected)
            return 1;

        if( createConnections( db_name, "localhost", dialog.login(), dialog.password() ) )
        {
            db_login = dialog.login();
            break;
        }
        
        QMessageBox::warning(0,"Warning","incorrect password or username\n"+error,QMessageBox::Ok);
    }

    MainWindow w( db_name, db_login );
    w.show();
    return a.exec();
}

PunX
Если делать таким вариантом то выдаёт error: no matching function for call to 'MainWindow::MainWindow(QString&, QString&)'
Litkevich Yuriy
лучше сделать отдельный диалог для настройки соединения с БД, при старте программы в конструкторе главного окна читать настройки из INI-файла, вызывать некий метод главного окна, который настроит соединение. А когда понадобится изменить настройки, вызывать диалог (он должен будет прочитать настройки из INI-файла), чтобы пользователь в вёл новые данные, если ввод успешен, то сохранять настройки в INI-файл и опять вызывать метод настраивающий соединение.

Цитата(PunX @ 12.4.2010, 0:55) *
MainWindow::MainWindow(QString&, QString&)'
дак ты напиши конструктор, который принимает логин и пароль.
BRE
Цитата(PunX @ 11.4.2010, 21:55) *
Если делать таким вариантом то выдаёт error: no matching function for call to 'MainWindow::MainWindow(QString&, QString&)'

Ну так напиши такой конструктор для MainWindow, который будет принимать эти параметры и сохранять/использовать их.

Для освоения Qt, необходимо знать C++. ;)
PunX
Попробую сделать с файлом конфигурации. Спасибо.
PunX
Работа через файл это конечно хорошо, но решил разобраться с другим вариантом, сдвиги есть, но результата положительного пока нет.
1.Создал конструктор
MainWindow::MainWindow(QString db_l, QString db_n)
{
db_login = db_l;
db_name = db_n;
}
db_name и db_login; объявленны public в классе MainWindow.
2.Создаю объекты
MainWindow db(db_name, db_login);
MainWindow w;
w.show();

3. Чтобы достать переменные, делаю следующее
QString l = MainWindow::db_login;
ui->label_3->setText(l);
Компиляция проходит без ошибок, но в label_3 ничего нет. Пока не могу понять в чём ошибка.
P.S. Извините за глупые вопросы, стараюсь во всём разобраться.
Litkevich Yuriy
Цитата(PunX @ 12.4.2010, 2:33) *
QString l = MainWindow::db_login;
а вот это что за запись? как ты её понимаешь?
PunX
Да, написал туфту наверное, но как правильно достать теперь переменную?
Litkevich Yuriy
Цитата(PunX @ 12.4.2010, 12:49) *
Да, написал туфту наверное, но как правильно достать теперь переменную?
ты объясни, чего ты ожидал от записи: MainWindow::db_login;
PunX
Ожидал что вернется значение переменной логин
Litkevich Yuriy
к членам объекта (экземпляра) класса обращаются так.
Извне класса
Если объект объявлен как скаляр:
MyClass object;
object.variableMember
object.functionMember()

если объект - указатель
MyClass *object;
object->variableMember
object->functionMember()


Внутри класса к своим членам обращаются не посредственно:
variableMember
functionMember()


Цитата(Litkevich Yuriy @ 12.4.2010, 12:54) *
MainWindow::db_login;
таким способом обращаются извне класса к статическим членам класса (т.е. к которым можно обращаться не создавая объект вообще).
Либо таким способом обращаться внутри класса к членам базового класса, от которого унаследован текущий класс
PunX
Спасибо за подробное разъяснение, но не понятно как сделать в моём случае? Я объект создаю в мэйн.цпп и передаю ему параметры, а использоваться полученные переменные должны в мэйнвиндоу.цпп.
Litkevich Yuriy
вот этот код:
QString l = MainWindow::db_login;
ui->label_3->setText(l);
в какой функции находится?
PunX
в функции void MainWindow::chengeEvent(QEvent *e) файла mainwindow.cpp
Litkevich Yuriy
Цитата(PunX @ 12.4.2010, 14:43) *
в функции void MainWindow::chengeEvent(QEvent *e)
т.е. внутри класса MainWindow, вот и смотри сообщение №44, там указано как обрщаться внутри класса к его собственным членам
PunX
Хм, прочитав ещё 44 сообщение, делаю следующее ui->label_3->setText(db_login); т.к. вызываю переменную внутри класса, создаю объекты в main.cpp
MainWindow db(db_name, db_login);
MainWindow w;
w.show();

но желаемого результата в label не нахожу.
BRE
Цитата(PunX @ 12.4.2010, 16:58) *
Хм, прочитав ещё 44 сообщение, делаю следующее ui->label_3->setText(db_login); т.к. вызываю переменную внутри класса, создаю объекты в main.cpp
MainWindow db(db_name, db_login);
MainWindow w;
w.show();

но желаемого результата в label не нахожу.

Для чего создавать два объекта MainWindow?
MainWindow w(db_name, db_login);
w.show();

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.