Russian Qt Forum

Qt => Вопросы новичков => Тема начата: palya от Февраль 01, 2016, 11:25



Название: Как осуществить передачу нескольких параметров сигналом?
Отправлено: palya от Февраль 01, 2016, 11:25
Добрый день.
Не понимаю как работать с сигналами. Есть сигнал textChanged() для QLineEdit, он меня устраивает. Я соединяю его с моим слотом и передаю только один параметр - const QString&. А как осуществить передачу нескольких параметров разного типа?


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: Racheengel от Февраль 01, 2016, 11:32
QVariantList, например?


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: palya от Февраль 01, 2016, 11:49
То есть от QLineEdit отказаться? А как тогда использовать textChanged()?


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: Bepec от Февраль 01, 2016, 11:49
Создать свой сигнал с нужными параметрами и подцепить на соответствующий слот.

Конкретизируйте что вы хотите сделать. Что вы хотите получить в конце?


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: palya от Февраль 01, 2016, 11:56
Мне нужен такой сигнал, который реагировал бы так же, как и textChanged(), но посылал бы вместе с QString ещё и два параметра int.


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: Igors от Февраль 01, 2016, 12:12
Мне нужен такой сигнал, который реагировал бы так же, как и textChanged(), но посылал бы вместе с QString ещё и два параметра int.
Ну а если
Цитировать
мне нужна такая же ф-ция/метод как вот эта, только с еще 2 параметрами
Как Вы понимаете придется самому ее написать, имеющаяся сама не превратится во что угодно.

С сигналами/слотами то же самое, но в данном случае свою писать вряд ли стоит, т.к. вставить ее вызовы в те же места что и textChanged не удастся - надо менять исходники Qt. Постарайтесь узнать нужные 2 значения др способом. 


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: gil9red от Февраль 01, 2016, 12:24
Мне нужен такой сигнал, который реагировал бы так же, как и textChanged(), но посылал бы вместе с QString ещё и два параметра int.

Самое простое и наглядное:
  • Создаете наследника QLineEdit
  • В него добавляете слот для обработки textChanged и сигнал для отправки QString, int, int
  • В конструкторе соединяете textChanged и тот слот
  • В слоте вызываете свой сигнал, добавляя в него нужные параметры


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: palya от Февраль 01, 2016, 12:34
Мне нужен такой сигнал, который реагировал бы так же, как и textChanged(), но посылал бы вместе с QString ещё и два параметра int.

Самое простое и наглядное:
  • Создаете наследника QLineEdit
  • В него добавляете слот для обработки textChanged и сигнал для отправки QString, int, int
  • В конструкторе соединяете textChanged и тот слот
  • В слоте вызываете свой сигнал, добавляя в него нужные параметры
А разве так получится? Если я передам сигнал textChanged только с одним параметром, то откуда в дальнейшем возьмутся другие?


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: Bepec от Февраль 01, 2016, 12:44
Вы создадите слот в наследнике QLineEdit, который будет вызываться от сигнала textChanged(const &QString), в котором вы будете отправлять созданный же вами сигнал myTextChanged(const &QString, int, int).


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: Igors от Февраль 01, 2016, 12:49
... то откуда в дальнейшем возьмутся другие?
Ниоткуда, все равно Вы сами должны их откуда-то взять. Говорите что нужно в этих интах, пока напрасно теряем время


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: palya от Февраль 01, 2016, 13:06
Вы создадите слот в наследнике QLineEdit, который будет вызываться от сигнала textChanged(const &QString), в котором вы будете отправлять созданный же вами сигнал myTextChanged(const &QString, int, int).
Цитировать
от сигнала textChanged(const &QString)
- значит только один аргумент попадает в слот в наследнике QLineEdit, а надо чтобы +2.
Цитировать
Говорите что нужно в этих интах
Отправлено: Сегодня в 12:44 Автор: Bepec
Переменные в main, которым присвоены координаты.


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: Bepec от Февраль 01, 2016, 13:32
Видимо в 1 раз не дошло, ну да повторю с уточнением
Вы создадите слот в наследнике QLineEdit, который будет вызываться от сигнала textChanged(const &QString), в котором вы будете отправлять созданный же вами сигнал myTextChanged(const &QString, int, int) с параметрами
const &QString - взятый из textChanged
ваши int,int, которые вы инициализируете в мейне.



Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: gil9red от Февраль 01, 2016, 13:42
Что-то вроде такого, набирал в браузере по памяти, но собраться должно :)
Код
C++ (Qt)
class MyLineEdit: public QLineEdit {
   Q_OBJECT
 
public:
   MyLineEdit() {
       connect(this, SIGNAL(textChanges(QString)), this, SLOT(textChanges(QString)));
   }
 
private slots:
   void slot_textChanges(QString text) {
       // Что-то делаете, высчитываете a и b
 
       emit myTextChanges(text, a, b);
   }
 
signals:
   void myTextChanges(QString, int, int);
};
 


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: Igors от Февраль 01, 2016, 13:56
Код
C++ (Qt)
   void slot_textChanges(QString text) {
       // Что-то делаете, высчитываете a и b
 
Ну а почему то же самое "что-то" не сделать в теле слота прицепленного на оригинальный textChanged ?
И нехорошо подавать дурной пример начинающим передавая аргументы по значению.

Переменные в main, которым присвоены координаты.
Ну и берите их оттуда как только получили textChanged, напр через extern, сигналы-то тут причем?


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: gil9red от Февраль 01, 2016, 14:03
И нехорошо подавать дурной пример начинающим передавая аргументы по значению.

QString достаточно умный, чтобы не по значению передаваться :) (где-то читал)
Да я и написал "Что-то вроде такого", а сам автор приводил семантику сигнала с const & QString, так что думаю, сам заменит на константную ссылку :)


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: Igors от Февраль 01, 2016, 14:28
QString достаточно умный, чтобы не по значению передаваться :) (где-то читал)
А ну как оторвут от маминой Qt сиси? (тут говорят мобильные платформы и все такое  :))


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: Bepec от Февраль 01, 2016, 14:36
Таки да, QString умён да и в передачи по значению нет ничего плохого. Ну разве что вы плисины программируете :D


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: gil9red от Февраль 01, 2016, 15:19
QString достаточно умный, чтобы не по значению передаваться :) (где-то читал)
А ну как оторвут от маминой Qt сиси? (тут говорят мобильные платформы и все такое  :))

С++/qt и на мобилки собирается :)
Да и там другие языки, в той же яве объекты передается по ссылке и только по ссылке, к простым типам это не относится, на то они и простые :)


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: palya от Февраль 02, 2016, 09:20
Пробовал, но понимания не хватает. Выложил исходный код примера и окончательный. Прошу помочь, если не сложно.

.cpp
Код:
#include <QtWidgets>
#include "counter.h"

void Counter::setValue(const QString& value)
{
    QWidget* wgt2 = new QWidget;
    Counter* ptxt2 = new Counter;
    QVBoxLayout* pvbxLayout2 = new QVBoxLayout;
    pvbxLayout2->addWidget(ptxt2);
    wgt2->setLayout(pvbxLayout2);
    wgt2->setAttribute(Qt::WA_ShowWithoutActivating);
    wgt2->setAttribute(Qt::WA_DeleteOnClose);
    wgt2->show();
}

int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    QWidget* wgt = new QWidget;
    Counter* ptxt = new Counter;

    QObject::connect(ptxt, SIGNAL(textChanged(const QString&)),
    ptxt, SLOT(setValue(const QString&)));

    QVBoxLayout* pvbxLayout = new QVBoxLayout;
    pvbxLayout->addWidget(ptxt);
    wgt->setLayout(pvbxLayout);
    wgt->setWindowFlags(wgt->windowFlags() | Qt::WindowStaysOnTopHint);
    wgt->setAttribute(Qt::WA_DeleteOnClose);
    wgt->show();
    int x = wgt->x();
    int y = wgt->y();
    return app.exec();
}
.h
Код:
#ifndef COUNTER_H
#define COUNTER_H
#include <QObject>
#include <QtWidgets>

class Counter : public QLineEdit
{
    Q_OBJECT

public slots:
    void setValue(const QString&);

};
#endif

После безуспешных попыток:
.cpp
Код:
#include <QtWidgets>
#include "counter.h"

void Counter::setValue(const QString& value)
{
    emit myTextChanged(const &QString value, int& x, int& y);
}
void Counter::setValue2(const QString& value, int&, int&)
{
QWidget* wgt2 = new QWidget;
Counter* ptxt2 = new Counter;
QVBoxLayout* pvbxLayout2 = new QVBoxLayout;
pvbxLayout2->addWidget(ptxt2);
wgt2->setLayout(pvbxLayout2);
wgt2->setAttribute(Qt::WA_ShowWithoutActivating);
wgt2->setAttribute(Qt::WA_DeleteOnClose);
wgt2->move(x,y);
wgt2->show();
}

int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    QWidget* wgt = new QWidget;
    Counter* ptxt = new Counter;

    QObject::connect(ptxt, SIGNAL(textChanged(const QString&)),
    ptxt, SLOT(setValue(const QString&)));
    QObject::connect(ptxt, SIGNAL(myTextChanged(const QString&, int&, int&)),
    ptxt, SLOT(setValue2(const QString&, int&, int&)));

    QVBoxLayout* pvbxLayout = new QVBoxLayout;
    pvbxLayout->addWidget(ptxt);
    wgt->setLayout(pvbxLayout);
    wgt->setWindowFlags(wgt->windowFlags() | Qt::WindowStaysOnTopHint);
    wgt->setAttribute(Qt::WA_DeleteOnClose);
    wgt->show();
    int x = wgt->x();
    int y = wgt->y();
    return app.exec();
}
.h
Код:
#ifndef COUNTER_H
#define COUNTER_H
#include <QObject>
#include <QtWidgets>

class Counter : public QLineEdit
{
    Q_OBJECT

public slots:
    void setValue(const QString&);
    void setValue2(const QString&, int&, int&);
signals:
    void myTextChanged(const QString&, int&, int&);

};
#endif


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: Bepec от Февраль 02, 2016, 09:29
Мдамс.  И оно у вас компилируется?


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: palya от Февраль 02, 2016, 09:31
Мдамс.  И оно у вас компилируется?
Нет, конечно. Это я, так сказать, изобразил ход мыслей.


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: Igors от Февраль 02, 2016, 10:08
То есть в слоте textChanged нужно знать x и y родительского окна? Тогда так
Код
C++ (Qt)
void Counter::textChanged( const QString & )
{
int x = this->window()->x():
int y = this->window()->y():
...
}


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: palya от Февраль 02, 2016, 10:20
То есть в слоте textChanged нужно знать x и y родительского окна? Тогда так
Код
C++ (Qt)
void Counter::textChanged( const QString & )
{
int x = this->window()->x():
int y = this->window()->y():
...
}
Спасибо, работает. Только я так и не понял всё вышеизложенное про сигнал от слота и extern, который я до этого нигде не встречал и не понял, как в данной ситуации я смог бы им воспользоваться.


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: Igors от Февраль 02, 2016, 10:36
Спасибо, работает. Только я так и не понял всё вышеизложенное про сигнал от слота и extern, который я до этого нигде не встречал и не понял, как в данной ситуации я смог бы им воспользоваться.
Ну extern вообще-то не лучшее решение, но его никто не отменял. Вот Вы сказали нужна переменная из main
Код
C++ (Qt)
// файл main.cpp
int theX, theY;  // объявляете нужные переменные глобальными
 
void main( ..)
{
 ...
 theX = MyCalcX(...);   // вычисляете значения
 theY = MyCalcY(...);
 ...
}
Здесь уже theX и theY средствами Qt не получить. Но можно так
Код
C++ (Qt)
// файл Counter.cpp
 
extern int theX;  // или объявить их в Counter.h или любом хедере видимом отсюда
extern int theY;  
 
void Counter::textChanged( const QString & )
{
...
 



Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: palya от Февраль 02, 2016, 10:47
Но тут, я так понимаю, определение слота, где проводятся операции над аргументами, переданными сигналом, должно быть реализовано в том же файле. А не так, как у меня - объявление в .h, а определение в main.cpp. Я правильно понимаю?
И нужен ли тогда дополнительный конструктор?


Название: Re: Как осуществить передачу нескольких параметров сигналом?
Отправлено: Igors от Февраль 02, 2016, 11:00
Но тут, я так понимаю, определение слота, где проводятся операции над аргументами, переданными сигналом, должно быть реализовано в том же файле. А не так, как у меня - объявление в .h, а определение в main.cpp. Я правильно понимаю?
И нужен ли тогда дополнительный конструктор?
Доступ к переменным из др файлов никак не связан с сигналами/слотами. Ведь theX и theY не их аргументы. Часто в таких случаях говорят типа
Цитировать
Возможно лучше отложить изучение Qt до тех пор пока будут твердые базовые знания в C++
Это не очень приятно слышать (да и эффект таких советов обычно как об стенку горох) - но ничего другого просто нет.