Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: xintrea от Июль 23, 2008, 12:08



Название: Передача данных из модального окна в основное через слот. Неполучается.
Отправлено: xintrea от Июль 23, 2008, 12:08
Здравствуйте!


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

Я делаю так. Вот код основного окна.

mainwindow.h
Код:
class mainwindow : public QMainWindow, public Ui::MainWindow
{
 ...
 private slots:
  // Слот, в котором вызывается модальное окно (вызывается из контекстного меню)
  void recordview_add_new_context(void);
 public slots:
  // Слот для приема данных из модального окна
  void recordview_add_new(QString name, QString text);
 ...
};

mainwindow.cpp
Код:
...
// Слот для открытия окошка добавления новой записи в таблицу
void mainwindow::recordview_add_new_context(void)
{
 qDebug() << "In slot recordview_add_new_context()";

 addnewrecord addnewrecordwin;

 connect(&addnewrecordwin, SIGNAL(signal_recordview_add_new(QString name, QString text)),
         this,             SLOT(recordview_add_new(QString name, QString text)));

 addnewrecordwin.exec();
}


// Слот добавления новой записи в таблицу коннечых записей
void mainwindow::recordview_add_new(QString name, QString text)
{
 qDebug() << "In slot recordview_add_new()";
   
 // Получение ссылки на модель таблицы конечных записей
 recordtablemodel *model=(recordtablemodel *)recordview->model();

 // Вставка данных в модель
 model->insert_new_record(name,text);
}
...


А вот код модального окна

addnewrecord.h
Код:
class addnewrecord : public QDialog, public Ui::addnewrecordform
{
Q_OBJECT

private slots:
 // Слот, вызыващийся при нажатии Ok
 void accept(void);

signals:
 // Сигнл для пересылки введенных данных.
 // Реалиацию сигнала делать не нужно, надо только описать его, и затем вызвать через emit
 void signal_recordview_add_new(QString name, QString text);

public:
 // Конструктор окна
 addnewrecord( QWidget * parent = 0, Qt::WFlags f = 0 );
};


addnewrecord.cpp
Код:
addnewrecord::addnewrecord( QWidget * parent, Qt::WFlags f) : QDialog(parent, f)
{
 setupUi(this);
}

void addnewrecord::accept(void)
{
 qDebug() << "In slot accept class addnewrecord";
 
 // Отправляются введенные пользователем данные
 emit signal_recordview_add_new(recordname->text(),recordtext->toHtml());
 
 // Закрывается окно
 this->setAttribute(Qt::WA_DeleteOnClose);
 this->close();
}

При запуске программы модальное окно открывается, можно ввести данные, при нажатии на OK появляется debug-строка "In slot accept class addnewrecord". И дальше должна появиться строка "In slot recordview_add_new()", которая бы свидетельствовала что данные приняты. Но она не появляется, т.е. данные не передаются в слот recordview_add_new().

Вопрос - что не так сделано, и как можно исправить?


Название: Re: Передача данных из модального окна в основное через слот. Неполучается.
Отправлено: pastor от Июль 23, 2008, 12:31
Причина такого поведения может быть в том что объект (диалог) уничтажаетсья.

А обязательно передввать данные через сингал\слот?

Я бы сделал немного нетак. Можно добавить два метода в диалог, например:

Код:
QString addnewrecord::recordName() const {recordname->text();}
QString addnewrecord::recordValue() const {recordtext->toHtml();}

Далее удалить addnewrecord::accept() и изменить mainwindow::recordview_add_new_context() :

Цитировать
void mainwindow::recordview_add_new_context(void)
{
    qDebug() << "In slot recordview_add_new_context()";

    addnewrecord addnewrecordwin;
    int ret = addnewrecordwin.exec();
    if (ret == QDialog::Rejected) return;

    recordview_add_new(addnewrecord.recordName(), addnewrecord.recordValue());
}

Примерно так.


Название: Re: Передача данных из модального окна в основное через слот. Неполучается.
Отправлено: xintrea от Июль 23, 2008, 13:11
Ну даже если убрать команды

Код:
 // Закрывается окно
 this->setAttribute(Qt::WA_DeleteOnClose);
 this->close();

то все равно слот не вызывается и данные не передаются.


Ваше решение впринципе подходит, но хотелось бы понять почему не работает то что в первом посте написано. А то я так никогда и не пойму, как работает механизм сигнал-слот.


Название: Re: Передача данных из модального окна в основное через слот. Неполучается.
Отправлено: Alex03 от Июль 23, 2008, 13:33
Цитировать
Note that the signal and slots parameters must not contain any variable names, only the type.

Цитировать
connect(&addnewrecordwin, SIGNAL(signal_recordview_add_new(QString name, QString text)),
         this, SLOT(recordview_add_new(QString name, QString text)));

Кстати в debug версии Вы должны увидеть чтото типа
Код:
Object::connect: No such signal ХХХХХХХХХХХ
Object::connect: No such slot ХХХХХХХХХХХ


Название: Re: Передача данных из модального окна в основное через слот. Неполучается.
Отправлено: xintrea от Июль 23, 2008, 14:14
Note that the signal and slots parameters must not contain any variable names, only the type.

Ага, в этом и было дело. Постоянно путаюсь, надо или нет указывать имена параметров. Потому что если описывать слот вот так

Код:
void recordview_select(const QModelIndex &index);

то имя параметра указывать можно.


Оказывается, имя указывать ненужно. Даже если строки в скобках в прототипе, реализации и в связке connect() будут одинаковыми, connect() не сможет создать соединение. В общем, при написании connect() имена указывать ненужно.


Название: Re: Передача данных из модального окна в основное через слот. Неполучается.
Отправлено: xintrea от Июль 23, 2008, 14:41
void mainwindow::recordview_add_new_context(void)
{
    qDebug() << "In slot recordview_add_new_context()";

    addnewrecord addnewrecordwin;
    int ret = addnewrecordwin.exec();
    if (ret == QDialog::Rejected) return;

    recordview_add_new(addnewrecord.recordName(), addnewrecord.recordValue());
}

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


Название: Re: Передача данных из модального окна в основное через слот. Неполучается.
Отправлено: Admin от Июль 23, 2008, 14:49
переменная окна видна только в теле функции
если вы хотите этого избежать - делайте все через new/delete


Название: Re: Передача данных из модального окна в основное через слот. Неполучается.
Отправлено: xintrea от Июль 23, 2008, 15:11
переменная окна видна только в теле функции
если вы хотите этого избежать - делайте все через new/delete

Не понял... Память от окна освободится в вышеприведенном коде? При постоянном открытии-закрытии окна добавления записи не будет ли утечки памяти?


Название: Re: Передача данных из модального окна в основное через слот. Неполучается.
Отправлено: lit-uriy от Июль 23, 2008, 15:14
утечки памяти возникают когда ты не корректно с указателями работаешь, а в коде который привел pastor, внутри функции создан объект, и при выходе из нее он перестанет существовать.