Здравствуйте! Столкнулся с проблемой при передаче данных от одной форме другой. Предлагали использовать сигналы-слоты, но формы не имеют указателя друг на друга чтобы через сигналы-слоты взаимодействовать. Как мне всё-таки сконнектить и осуществить передачу данных между двумя формами?
neneTc,
В main.cpp нет указателя на второе окно
а как осуществить передачу через коннект?
http://wiki.crossplatform.ru/index.php/%D0%A1%D0%B8%D0%B3%D0%BD%D0%B0%D0%BB%D1%8B_%D0%B8_%D1%81%D0%BB%D0%BE%D1%82%D1%8B_%28Qt%29
Спасибо) После 3 дней втыкания в различные маны всё заработало! Наконец-то)
Есть у меня Главное окно и Диалоговое. Мне нужно передать данные из Диалогового окна в Главное.
Делаю так:
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)));
Вопрос:
1) Диалоговое окно модальное?
Диалоговое окно, но лучше наверно сделать модальное.
mainwindow.cpp
void MainWindow::LoginSys()
{
if (!EnterDialog)
{
EnterDialog = new LoginSysDialog(this);
}
EnterDialog->show();
EnterDialog->activateWindow();
}
обычно данные из диалоговых окон передаются в главное, по закрытию диалогового окна.
Для этого в диалоговом окне предусматривают методы чтения данных.
Например, для чтения текста из 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
#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, но это не помогло.
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
#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.
Сейчас формы вызываются, всё вроде работает. Перечитал все соообщения в теме сначала, но не понял как теперь связать эти две формы? как сделать чтобы при удачном завершении формы входа, открывалось основное окно? (Подозреваю что всё это делается с помощью slot-ов?)
Поставлю вопрос по другому, можно ли сделать так чтобы сначала запускалось окно входа (логин), при получении данных с него, открывалось главное окно, а окно логина закрывалось?
Извините может за глупые вопросы, могли бы вы привести пример как вызвать диалог для создания главного окна?
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();
}
Всё прекрасно работает и окно входа и потом запускается главное окно, НО появилась такая потребность получить в главное окно логин пользователя который был введён в окне входа. Способ из http://www.forum.crossplatform.ru/index.php?s=&showtopic=4492&view=findpost&p=31936 этой темы не подходит, т.к. диалоговое окно входа (где вводится логин и пароль) вызывается в 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
#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();
}
Доступны для того чтобы вывести их на форму, т.е. доступны в 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&)'
лучше сделать отдельный диалог для настройки соединения с БД, при старте программы в конструкторе главного окна читать настройки из INI-файла, вызывать некий метод главного окна, который настроит соединение. А когда понадобится изменить настройки, вызывать диалог (он должен будет прочитать настройки из INI-файла), чтобы пользователь в вёл новые данные, если ввод успешен, то сохранять настройки в INI-файл и опять вызывать метод настраивающий соединение.
Попробую сделать с файлом конфигурации. Спасибо.
Работа через файл это конечно хорошо, но решил разобраться с другим вариантом, сдвиги есть, но результата положительного пока нет.
1.Создал конструктор
MainWindow::MainWindow(QString db_l, QString db_n)
{
db_login = db_l;
db_name = db_n;
}
db_name и db_login; объявленны public в классе MainWindow.MainWindow db(db_name, db_login);
MainWindow w;
w.show();
QString l = MainWindow::db_login;
ui->label_3->setText(l);
Компиляция проходит без ошибок, но в label_3 ничего нет. Пока не могу понять в чём ошибка.Да, написал туфту наверное, но как правильно достать теперь переменную?
Ожидал что вернется значение переменной логин
к членам объекта (экземпляра) класса обращаются так.
Извне класса
Если объект объявлен как скаляр:
MyClass object;
object.variableMember
object.functionMember()
MyClass *object;
object->variableMember
object->functionMember()
variableMember
functionMember()
Спасибо за подробное разъяснение, но не понятно как сделать в моём случае? Я объект создаю в мэйн.цпп и передаю ему параметры, а использоваться полученные переменные должны в мэйнвиндоу.цпп.
вот этот код:
QString l = MainWindow::db_login;
ui->label_3->setText(l);
в какой функции находится?
в функции void MainWindow::chengeEvent(QEvent *e) файла mainwindow.cpp
Хм, прочитав ещё 44 сообщение, делаю следующее ui->label_3->setText(db_login); т.к. вызываю переменную внутри класса, создаю объекты в main.cpp
MainWindow db(db_name, db_login);
MainWindow w;
w.show();
MainWindow db(db_name, db_login);
MainWindow w;
w.show();
MainWindow w(db_name, db_login);
w.show();
Если сделать show() для объекта db то приложение рушиться.
На данный момент у меня в MainWindow 2 конструктора
MainWindow(QWidget *parent);
MainWindow(QString db_l, QString db_n);
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::MainWindow(QString db_l, QString db_n)
{
db_login = db_l;
db_name = db_n;
}
Первый консруктор тебе не нужен, ведь ты должен обязательно получить db_login и db_name.
MainWindow::MainWindow(QString db_l, QString db_n, QWidget *parent ) :
QMainWindow(parent),
ui(new Ui::MainWindow),
db_login( db_l ),
db_name( db_n )
{
ui->setupUi(this);
}
Я наверное уже замучал всякими вопросами дурацкими, но довести до конца и разобраться хочется, определил такой конструктор вместо тех двух, теперь создаю объект
MainWindow m(db_login,db_name); такой вариант конечно же не пойдёт
но и такой MainWindow m(db_login,db_name,QWidget *parent); тоже не проходит.
В файле mainwindow.h декларируй его так:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow::MainWindow( QString db_l, QString db_n, QWidget *parent = 0 );
};
О, заработало Спасибо!
Но пока сыплються ворнинги
mainwindow.h:23: warning: 'MainWindow::ui' will be initialized after
на строку Ui::MainWindow *ui;mainwindow.h:14: warning: 'QString MainWindow::db_login'
на строку QString db_login;mainwindow.cpp:5: warning: when initialized here
строка MainWindow::MainWindow(QString db_l, QString db_n, QWidget *parent ) .....
Покажи, что у тебя в mainwindow.h и mainwindow.cpp.
Спасибо большое за "разжёвывание" матерьяла и за терпение!
я предлагаю тему переместить из Qt в технику программирования, т.к. тут вопросы только по С/С++
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();
}
#ifndef NEWDOG_H
#define NEWDOG_H
#include <QDialog>
namespace Ui {
class newdog;
}
class newdog : public QDialog
{
Q_OBJECT
public:
explicit newdog(QWidget *parent = 0);
~newdog();
QString aname() const;
private:
Ui::newdog *ui;
private slots:
void on_buttonBox_accepted();
};
#endif // NEWDOG_H
#include "newdog.h"
#include "ui_newdog.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"
newdog::newdog(QWidget *parent) :
QDialog(parent),
ui(new Ui::newdog)
{
ui->setupUi(this);
}
newdog::~newdog()
{
delete ui;
}
void newdog::on_buttonBox_accepted()
{
}
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "newdog.h"
#include "QDialog"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_2_clicked()
{
QString name;
newdog form(this);
if (form.exec() == QDialog::Accepted)
{
name=form.aname();
}
ui->label->setText(name);
}
void MainWindow::on_pushButton_2_clicked(bool checked)
{
}
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)