Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: Victor007 от Июль 13, 2013, 21:41



Название: Передать значение переменной
Отправлено: Victor007 от Июль 13, 2013, 21:41
Ситуация следующая: у меня есть две формы (Widget1 и Widget2), одна открывается из другой по нажатию кнопки. В первой форме также есть comboBox и мне надо передать во вторую значение индекса comboBox (comboBox->currentIndex) из первой. То есть, мне нужно делать какие-то операции со значением, получаемым в первой форме: int a=ui->comboBox->currentIndex(). Вот эту переменную "а" мне и надо использовать во второй форме. Я вот что придумал: можно задать в первом виджете signal sendIndex1(int a), сделать emit sendIndex1(int a) по нажатию кнопки и получить его одновременно с открытием второго виджета. Вопрос в том, что цеплять к этому сигналу? И вообще, в правильном ли я направлении пытаюсь двигаться? Заранее спасибо.


Название: Re: Передать значение переменной
Отправлено: Old от Июль 13, 2013, 21:52
Какие сигналы? :)

Код
C++ (Qt)
void Widget1::clickButton()
{
   int idx=ui->comboBox->currentIndex();
   Widget2 w2( idx, this );
   w2.exec();
}
 


Название: Re: Передать значение переменной
Отправлено: Victor007 от Июль 14, 2013, 00:30
Спасибо! Но widget1.cpp "не знает" до нажатия на кнопку, что ему передастся значение idx и при компилляции выдает ошибку "'idx':undeclared identifier". Кроме того, есть еще две ошибки:
'Widget2::Widget2': no overloaded function takes 2 arguments
'exec': is not a member of 'Widget2'

Widget2 у меня задается соответственно в main.cpp:
 Widget2 *w2 = new Widget2;


Название: Re: Передать значение переменной
Отправлено: gil9red от Июль 14, 2013, 03:16
exec есть у QDialog и QMenu (кст, они оба наследуются от QWidget), а раз у вас не они, используйте show()

Понятия не имею как у вас выглядит структура программы, но раз вас нужно чтобы Widget2 принимал сигнал, создайте у него слот и подключите к нему сигнал :)

Слоты создаются так:
Код:
class Widget2: public QWidget
{
Q_OBJECT

public slots:
    void takeIndex(int a)
    {
     // какие то шаманские действия
    }
};

Подключаем сигнал к слоту:
Код:
Widget2 *w2 = new Widget2();
connect(w1, SIGNAL(sendIndex1(int), w2, SLOT(takeIndex(int)));

Если подключение сигнала будет в коде класса Widget1, тогда так:
Код:
Widget2 *w2 = new Widget2();
connect(this, SIGNAL(sendIndex1(int), w2, SLOT(takeIndex(int)));

Ну вроде, все понятно объяснил  :D


Название: Re: Передать значение переменной
Отправлено: _Vitaliy_ от Июль 14, 2013, 09:48
Не на правах рекламы (не мое) http://easy-qt.blogspot.ru/2012/10/1.html (http://easy-qt.blogspot.ru/2012/10/1.html)


Название: Re: Передать значение переменной
Отправлено: Victor007 от Июль 14, 2013, 15:14
gil9red, спасибо! Как-то так я изначально и думал делать. Но undeclared identifier остался. Ведь "шаманские действия" я делаю реально в widget2.cpp, а класс описан в widget2.h. Чтобы было понятнее я приведу код, он очень короткий:
widget2.h
Код:
#ifndef WIDGET2_H
#define WIDGET2_H

#include <QWidget>

namespace Ui {
class widget2;
}

class widget2 : public QWidget
{
    Q_OBJECT
    
public:
    explicit widget2(QWidget *parent = 0);
    ~widget2();
    
private:
    Ui::widget2 *ui;

public slots:
    void takeIndex(int a);
//    {
//     // какие то шаманские действия
//    }
};
#endif // WIDGET2_H

widget2.cpp
Код:
#include "widget1.h"
#include "widget2.h"
#include "ui_widget2.h"

widget2::widget2(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::widget2)
{
    ui->setupUi(this);
    ui->spinBox->setValue(a+1); //для простоты что-то совсем тривиальное
}

widget2::~widget2()
{
    delete ui;
}

main.cpp
Код:
#include "widget1.h"
#include "widget2.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget1 *w = new Widget1;
    widget2 *w2 = new widget2;

    QObject::connect(w, SIGNAL(openw2()),w2, SLOT(show())); //вторая форма открывается из первой
    QObject::connect(w, SIGNAL(sendspinIndex1(int)),w2, SLOT(takeIndex(int))); //заветное число a

    w->show();
    
    return a.exec();
}

То есть щелкаем spinBox на одной форме, а на другой отображается в аналогичном элементе число, большее на единицу (постарался максимально упростить, чтобы было понятнее).


Название: Re: Передать значение переменной
Отправлено: gil9red от Июль 14, 2013, 16:39
Слот эта тот же метод (функция), потому нужно его тоже описывать.
В h файле, вы объявили, что будет у вас слот void takeIndex(int a), а в cpp опишите функцию.

widget2.h
Код:
#ifndef WIDGET2_H
#define WIDGET2_H

#include <QWidget>

namespace Ui {
class widget2;
}

class widget2 : public QWidget
{
    Q_OBJECT
    
public:
    explicit widget2(QWidget *parent = 0, int a);
    ~widget2();
    
private:
    Ui::widget2 *ui;

public slots:
    void takeIndex(int a);
};
#endif // WIDGET2_H


widget2.cpp
Код:
#include "widget1.h"
#include "widget2.h"
#include "ui_widget2.h"

widget2::widget2(QWidget *parent, int a) :
    QWidget(parent),
    ui(new Ui::widget2)
{
    ui->setupUi(this);
    ui->spinBox->setValue(a+1); //для простоты что-то совсем тривиальное
}

widget2::~widget2()
{
    delete ui;
}

void widget2::takeIndex(int a)
{
   // какие то действия...
    // например, пусть индекс отобразится в заголовке окна
   setWindowTitle(QString("Индекс: %1").arg(a));
}


main.cpp
Код:
#include "widget1.h"
#include "widget2.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget1 *w = new Widget1();

// пусть a будет равно 1
    int a = 1;
    widget2 *w2 = new Widget2(0, // то есть у w2 нет родителя
                                           a); // вставляем число

    QObject::connect(w, SIGNAL(openw2()),w2, SLOT(show()));
    QObject::connect(w, SIGNAL(sendspinIndex1(int)),w2, SLOT(takeIndex(int)));

    w->show();
    
    return a.exec();
}

Теперь при создании Widget2 он будет получать какое то число, а какое именно, мы должны сами указать.
Если это число берется из Widget1, то возвращайте его из Widget1 и вставляйте в Widget2
Как вставить число я показал.

И советую немного прочесть по классам с++ :)


Название: Re: Передать значение переменной
Отправлено: Victor007 от Июль 14, 2013, 17:12
Ага, спасибо, так заработало. Да, все объяснение предельно понятно, в h описываем прототип функции в cpp саму функцию. Я, честно говоря, Си длительное время изучал, просто все уже подзабылось, да и особенности qt очень специфические: сигналы, слоты..  В любом случае, спасибо за помощь.
PS: Хотелось бы еще услышать от Old комментарии к его реализации. Я так понял, она должна быть проще.


Название: Re: Передать значение переменной
Отправлено: Old от Июль 14, 2013, 17:15
PS: Хотелось бы еще услышать от Old комментарии к его реализации. Я так понял, она должна быть проще.
Как я понял по первому посту, то нужно взять индекс активного элемента combobox и передать его во второй виджет, который создается в слоте первого виджета. Вот мой вариант - передать его через конструктор второго виджета в качестве параметра.


Название: Re: Передать значение переменной
Отправлено: Victor007 от Июль 14, 2013, 21:55
Ну да, так выглядит намного проще. Только я написал, что при этом получаем ошибки. Видимо, надо что-то прописать в widget2.cpp?


Название: Re: Передать значение переменной
Отправлено: kambala от Июль 14, 2013, 22:10
ты можешь свой полный код привести? а то по огрызкам непонятно где ошибка.


Название: Re: Передать значение переменной
Отправлено: Victor007 от Июль 14, 2013, 23:03
Да, конечно. Это программа соответственно с попыткой реализации по Old. Если удобнее выложить по-другому, скажите, сделаю, как надо.



Название: Re: Передать значение переменной
Отправлено: Victor007 от Июль 14, 2013, 23:07
И main.cpp


Название: Re: Передать значение переменной
Отправлено: kambala от Июль 14, 2013, 23:20
еще один, не знающий что такое архив.

ошибка-то что говорит (текст и место)? быстрее ведь посмотреть в конкретном файле что написано не так, чем качать все файлы по отдельности, создавать самому проект.


Название: Re: Передать значение переменной
Отправлено: Victor007 от Июль 14, 2013, 23:31
Дык архив не добавляется! Пишет, что очень большой, хотя куда уж меньше.. Ошибки все приводил во втором посте.


Название: Re: Передать значение переменной
Отправлено: kambala от Июль 14, 2013, 23:42
в архив надо сложить все прикрепленные тобой файлы и файл с расширением .pro, больше туда ничего не надо совать.

во втором сообщении место ошибки (имя файла и номер строки) не приведены.

с английским у тебя как — совсем туго? про онлайн переводчики не слышал? надо ж хотя бы попытаться понять что ошибка говорит.
Цитировать
exec есть у QDialog и QMenu (кст, они оба наследуются от QWidget), а раз у вас не они, используйте show()
один ответ про ошибку уже давно дали.

конструктор класса widget2 не может взять параметр (твой int a) из воздуха — его надо прописывать. если что надо сделать — непонятно, то лучше для начала заняться изучением С++.

при создании переменной типа widget2 не как указатель она умрет по выходе из метода, т.е. окно не появится.

в данном случае emit openw2() является абсолютно бессмысленным действием т.к. ты можешь вызвать метод show() у переменной типа widget2 напрямую.


Название: Re: Передать значение переменной
Отправлено: Victor007 от Июль 15, 2013, 02:13
Послушайте, если Вам кажется, что я пишу полную ерунду, может, просто не стоит отвечать? Спасибо, конечно, за ответ. Си я изучал в школе и институте, с английским, вроде, все нормально. Вы поймите, у меня рабочий день сейчас по 10-11 часов в сутки, читать снова учебники времени никакого нет. Пользуюсь самим этим форумом, как учебником, правил вроде стараюсь не нарушать. Всем, кстати, большое спасибо за оперативные ответы и помощь. Кстати, не соглашусь, что, изучив С/C++, можно в принципе легко перейти на язык высокого уровня: есть много примеров людей в возрасте за 40, которые в свое время были на переднем крае науки и программировали еще на кодах (даже не на ассемблере) и не смогли перейти на объектно-ориентированное программирование. Собственно проблема уже решена была, просто, если есть возможность подсказать по другому пути решения, я буду благодарен.
Теперь смотрите:  emit openw2() я написал по совету опять же кого-то с форума, так эта штука работает. Как Вы говорите w2->show() или w2.show она не работает. Почему, это другой вопрос. Конечно, заманчиво напрямую задать метод show  у widget2. Я подозреваю, что так будет существенный выигрыш по скорости. Но у меня так не получилось сделать, повторяю.
Сделал, как Вы написали, попробовал собрать проект, но так он не собирается. Не знаю, как Вы думаете его собрать без ui (только, пожалуйста, воспринимайте это исключительно как вопрос без эмоционального подтекста). Заархивировал в zip.
Еще раз спасибо!
PS: Я повторюсь, для меня Qt - штука новая, если какие-то вопросы слишком наивны - это не от моей лени или полного незнания, просто не так легко перейти в новую среду программирования, особенно непрофессионалу.
PPS: Могу задавать все вопросы в разделе для новичков, если так будет лучше.


Название: Re: Передать значение переменной
Отправлено: kambala от Июль 15, 2013, 11:35
Цитировать
Послушайте, если Вам кажется, что я пишу полную ерунду, может, просто не стоит отвечать?
про полную ерунду я нигде не говорил. если человек делает что-то не так или не понимает чего-то, не вижу ничего плохого в том, чтобы ему на это указать, чтобы впредь он так не поступал.
Цитировать
Вы поймите, у меня рабочий день сейчас по 10-11 часов в сутки, читать снова учебники времени никакого нет. Пользуюсь самим этим форумом, как учебником, правил вроде стараюсь не нарушать.
интересно почему проблема незнания языка (именно языка С++, а не фреймворка Qt) должна стать нашей. у нас тут не учители и не преподаватели, а отдельные части книги или какие-нибудь статьи в интернете можно и перечитать.
Цитировать
Кстати, не соглашусь, что, изучив С/C++, можно в принципе легко перейти на язык высокого уровня
С/C++ — это и так языки высокого уровня, Qt — это не язык (на всякий случай уточню).
Цитировать
Теперь смотрите:  emit openw2() я написал по совету опять же кого-то с форума, так эта штука работает.
этот совет был дан, когда никакого кода толком видно не было. в данном случае этот эмит лишний.
Цитировать
Сделал, как Вы написали, попробовал собрать проект, но так он не собирается. Не знаю, как Вы думаете его собрать без ui (только, пожалуйста, воспринимайте это исключительно как вопрос без эмоционального подтекста). Заархивировал в zip.
действительно, там еще .ui файлы подключаются, не заметил. но даже без них в данном случае заставить проект компилироваться будет быстро.
Цитировать
PPS: Могу задавать все вопросы в разделе для новичков, если так будет лучше.
лучше, ведь раздел специально для новичков :)

при текущем коде, если ты хочешь одновременно и показать виджет2 и передать ему число, то надо написать свой слот с параметром, к которому надо будет приконнектиться (вместо show()), переделать сигнал openw2, чтобы он тоже передавал параметр, и в слоте написать установку значения в спинбокс и вызов show().


Название: Re: Передать значение переменной
Отправлено: Igors от Июль 15, 2013, 14:13
Вы поймите, у меня рабочий день сейчас по 10-11 часов в сутки, читать снова учебники времени никакого нет. Пользуюсь самим этим форумом, как учебником, ..
Опять эта до боли знакомая песня :'( Покажите как собрать учебный проект, как подключать слоnы/сигналы, объясните основы языка и.т.п. - но при этом считайтесь с моим мнением, и да, "будьте терпимее" (как до кадр давеча писал).

А Вы не подумали - а кому оно надо? Может, мягко говоря, "не очень хорошо" быть другим обузой? И на что Вы рассчитываете - научиться программировать только используя форум? Это нереально и наивно. Нет у Вас времени самостоятельно заниматься - не морочьте голову себе и людям только для того чтобы стать очередным говнокодером, их и так с переизбытком.


Название: Re: Передать значение переменной
Отправлено: Bepec от Июль 15, 2013, 14:15
Ну научиться на форуме можно. Криво, сложно, долго, но можно.

Хотя второго Spark'a  я тут не хочу :P