Здравствуйте! Столкнулся с проблемой при передаче данных от одной форме другой. Предлагали использовать сигналы-слоты, но формы не имеют указателя друг на друга чтобы через сигналы-слоты взаимодействовать. Как мне всё-таки сконнектить и осуществить передачу данных между двумя формами?
neneTc,
Цитата(neneTc @ 9.3.2010, 17:02)
формы не имеют указателя друг на друга
это не обязательно, соединять и разъединять можно в любом месте программы. хоть в
main.cpp главное чтоб там указатели были.
В main.cpp нет указателя на второе окно
Цитата(neneTc @ 9.3.2010, 17:08)
В main.cpp нет указателя на второе окно
ну я для примера сказал
где то же есть место где есть оба указателя на кона?
если нет создай его.(место)
а как осуществить передачу через коннект?
Спасибо) После 3 дней втыкания в различные маны всё заработало! Наконец-то)
Цитата(neneTc @ 10.3.2010, 1:16)
Спасибо) После 3 дней втыкания в различные маны всё заработало! Наконец-то)
А можно подробнее что да как?
Litkevich Yuriy
21.3.2010, 20:16
Цитата(Vexar @ 19.3.2010, 6:55)
А можно подробнее что да как?
что именно не понятно?
Есть у меня Главное окно и Диалоговое. Мне нужно передать данные из
Диалогового окна в
Главное.
Делаю так:
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
22.3.2010, 1:39
Вопрос:
1) Диалоговое окно модальное?
Диалоговое окно, но лучше наверно сделать модальное.
mainwindow.cpp
void MainWindow::LoginSys()
{
if (!EnterDialog)
{
EnterDialog = new LoginSysDialog(this);
}
EnterDialog->show();
EnterDialog->activateWindow();
}
Litkevich Yuriy
22.3.2010, 10:38
обычно данные из диалоговых окон передаются в главное, по закрытию диалогового окна.
Для этого в диалоговом окне предусматривают методы чтения данных.
Например, для чтения текста из 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();
}
Здравствуйте, я своём приложении мне необходимо сделать следующее: при запуске появляется окно где пользоветль вводит логин и пароль, после успешной авторизации появляется основное(главное) окно программы.
Я делаю следующее:
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;
}
Но даже на этом шаге компиляция рушиться с ошибками. Подскажите пожалуйста, на каком шаге делаю что-то не так?
А почему неймспейс называется Li::? По-умолчанию uic вроде генерирует Ui::
namespace Li {
class MyForm;
}
Да, это исправил заменил на Ui, но это не помогло.
Цитата(PunX @ 8.4.2010, 20:20)
Да, это исправил заменил на Ui, но это не помогло.
private:
Ui::MyForm *li;
}
отредактировал до такого состояния, ошибок стало вроде меньше, но всё ранво не пойму что не так
.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;
}
#include "dialog_login.h"
login::login(QDialog *parent) : QDialog(parent),ui(new Ui::login)
{
ui->setupUi(this);
}
А лучше покажи сразу все ошибки.
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.
вот все которые вылетают, может я свою задачу не так реализовываю? может можно проще всё сделать?
А точно в файле ui_dialog_login.h класс называется login?
С учетом регистра и т.д.?
Спасибо нашёл ошибку) надо было имя класса поменять на Dialog.
Litkevich Yuriy
8.4.2010, 19:53
Цитата(PunX @ 8.4.2010, 23:04)
:QDialog(parent), li(new Li::MyForm())
в конструктор MyForm наверняка надо передать
this и не удалять его руками в последствии
Сейчас формы вызываются, всё вроде работает. Перечитал все соообщения в теме сначала, но не понял как теперь связать эти две формы? как сделать чтобы при удачном завершении формы входа, открывалось основное окно? (Подозреваю что всё это делается с помощью slot-ов?)
Поставлю вопрос по другому, можно ли сделать так чтобы сначала запускалось окно входа (логин), при получении данных с него, открывалось главное окно, а окно логина закрывалось?
Litkevich Yuriy
8.4.2010, 22:10
Цитата(PunX @ 9.4.2010, 0:03)
Подозреваю что всё это делается с помощью slot-ов?
нет. Я приводил пример в
сообщении №13Цитата(PunX @ 9.4.2010, 2:09)
так чтобы сначала запускалось окно входа (логин), при получении данных с него, открывалось главное окно, а окно логина закрывалось?
тогда вызывай диалог до создания главного окна
Извините может за глупые вопросы, могли бы вы привести пример как вызвать диалог для создания главного окна?
Litkevich Yuriy
9.4.2010, 7:06
Цитата(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();
}
Всё прекрасно работает и окно входа и потом запускается главное окно, НО появилась такая потребность получить в главное окно логин пользователя который был введён в окне входа. Способ из
13 сообщения этой темы не подходит, т.к. диалоговое окно входа (где вводится логин и пароль) вызывается в main.cpp и получить данные в других модулях не получается.
Можно передать их в конструкторе 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();
}
Вообщем у меня получилось такое
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 были доступны и эти переменные можно было использовать?
Цитата(PunX @ 11.4.2010, 21:32)
как сделать так чтобы db_username,db_dbname были доступны и эти переменные можно было использовать?
Доступны где?
Доступны для того чтобы вывести их на форму, т.е. доступны в mainwindow.cpp.
Можно, например так:
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();
}
Если делать таким вариантом то выдаёт error: no matching function for call to 'MainWindow::MainWindow(QString&, QString&)'
Litkevich Yuriy
11.4.2010, 20:58
лучше сделать отдельный диалог для настройки соединения с БД, при старте программы в конструкторе главного окна читать настройки из INI-файла, вызывать некий метод главного окна, который настроит соединение. А когда понадобится изменить настройки, вызывать диалог (он должен будет прочитать настройки из INI-файла), чтобы пользователь в вёл новые данные, если ввод успешен, то сохранять настройки в INI-файл и опять вызывать метод настраивающий соединение.
Цитата(PunX @ 12.4.2010, 0:55)
MainWindow::MainWindow(QString&, QString&)'
дак ты напиши конструктор, который принимает логин и пароль.
Цитата(PunX @ 11.4.2010, 21:55)
Если делать таким вариантом то выдаёт error: no matching function for call to 'MainWindow::MainWindow(QString&, QString&)'
Ну так напиши такой конструктор для MainWindow, который будет принимать эти параметры и сохранять/использовать их.
Для освоения Qt, необходимо знать C++.
Попробую сделать с файлом конфигурации. Спасибо.
Работа через файл это конечно хорошо, но решил разобраться с другим вариантом, сдвиги есть, но результата положительного пока нет.
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
12.4.2010, 8:32
Цитата(PunX @ 12.4.2010, 2:33)
QString l = MainWindow::db_login;
а вот это что за запись? как ты её понимаешь?
Да, написал туфту наверное, но как правильно достать теперь переменную?
Litkevich Yuriy
12.4.2010, 8:54
Цитата(PunX @ 12.4.2010, 12:49)
Да, написал туфту наверное, но как правильно достать теперь переменную?
ты объясни, чего ты ожидал от записи:
MainWindow::db_login;
Ожидал что вернется значение переменной логин
Litkevich Yuriy
12.4.2010, 9:23
к членам объекта (экземпляра) класса обращаются так.
Извне класса
Если объект объявлен как скаляр:
MyClass object;
object.variableMember
object.functionMember()
если объект - указатель
MyClass *object;
object->variableMember
object->functionMember()
Внутри класса к своим членам обращаются не посредственно:
variableMember
functionMember()
Цитата(Litkevich Yuriy @ 12.4.2010, 12:54)
MainWindow::db_login;
таким способом обращаются извне класса к статическим членам класса (т.е. к которым можно обращаться не создавая объект вообще).
Либо таким способом обращаться внутри класса к членам базового класса, от которого унаследован текущий класс
Спасибо за подробное разъяснение, но не понятно как сделать в моём случае? Я объект создаю в мэйн.цпп и передаю ему параметры, а использоваться полученные переменные должны в мэйнвиндоу.цпп.
Litkevich Yuriy
12.4.2010, 9:40
вот этот код:
QString l = MainWindow::db_login;
ui->label_3->setText(l);
в какой функции находится?
в функции void MainWindow::chengeEvent(QEvent *e) файла mainwindow.cpp
Litkevich Yuriy
12.4.2010, 13:26
Цитата(PunX @ 12.4.2010, 14:43)
в функции void MainWindow::chengeEvent(QEvent *e)
т.е. внутри класса MainWindow, вот и смотри сообщение №44, там указано как обрщаться внутри класса к его собственным членам
Хм, прочитав ещё 44 сообщение, делаю следующее ui->label_3->setText(db_login); т.к. вызываю переменную внутри класса, создаю объекты в main.cpp
MainWindow db(db_name, db_login);
MainWindow w;
w.show();
но желаемого результата в label не нахожу.
Цитата(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();
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.