Russian Qt Forum

Qt => Общие вопросы => Тема начата: Olzhas от Март 08, 2010, 01:28



Название: сигналы Combobox
Отправлено: Olzhas от Март 08, 2010, 01:28
Всем добрый вечер.

Столкнулся со странной проблемой. Мне нужно сделать так, чтобы при изменения item'а combobox'а выполнялась некая функция XXX.

пробовал и так...
connect(ui.comboBox,SIGNAL(ui.comboBox->currentIndexChanged(QString& str)),this,SLOT(XXX()));

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

Заранее спасибо.


Название: Re: сигналы Combobox
Отправлено: f0x от Март 08, 2010, 03:27
убери str


Название: Re: сигналы Combobox
Отправлено: Olzhas от Март 08, 2010, 11:00
не помогает(( я ж говорю как только не пробовал


Название: Re: сигналы Combobox
Отправлено: BRE от Март 08, 2010, 11:02
Код
C++ (Qt)
connect( ui.comboBox, SIGNAL( currentIndexChanged( const QString & ) ), this, SLOT( XXX() ) );


Название: Re: сигналы Combobox
Отправлено: Olzhas от Март 08, 2010, 12:30
Не помогло.
У кого- нибудь есть опыт удачной обработки сигналов от комбика, киньте пример плиз.


Название: Re: сигналы Combobox
Отправлено: BRE от Март 08, 2010, 12:34
Не помогло.
Не верю.  ;)

Покажи побольше кода и желательно, то что программа пишет в консоль при своей работе...


Название: Re: сигналы Combobox
Отправлено: SABROG от Март 08, 2010, 13:04
Код
C++ (Qt)
connect( ui.comboBox, SIGNAL( currentIndexChanged( const QString & ) ), this, SLOT( XXX() ) );

Форматирование это конечно хорошо, но оно замедляет код при частом вызове connect. Qt удаляет все "const", "&" и пробельные символы. Это называется нормализацией, чтобы чуток повысить скорость Qt нужно помогать:
Код
C++ (Qt)
connect( ui.comboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(XXX()));
 

Qt никогда не передает параметры через сигналы или события в виде ссылок или указателей, объект всегда копируется.


Название: Re: сигналы Combobox
Отправлено: BRE от Март 08, 2010, 13:35
Qt никогда не передает параметры через сигналы или события в виде ссылок или указателей, объект всегда копируется.
Что под этим подразумевается?
При DirectConnection вызов слота сводиться к прямому вызову метода. И если этот метод использует ссылки/указатели для передачи аргументов, то ему будут переданы ссылки/указатели.


Название: Re: сигналы Combobox
Отправлено: SABROG от Март 08, 2010, 14:07
Что под этим подразумевается?

Когда я это писал, то подразумевал именно эвенты. Про Qt::DirectConnect забыл как-то. Ты прав, в этом случае всё как и ожидается. Если взять такой пример:

Код
C++ (Qt)
void MainWindow::on_pushButton_clicked()
{
   qDebug() << &str;
   emit someSignal(str);
}
 

Код
C++ (Qt)
void MainWindow::someSlot(const QString &str)
{
   qDebug() << &str;
}
 

То в зависимости от типа подключения:

Код
C++ (Qt)
QObject::connect(this, SIGNAL(someSignal(QString)), SLOT(someSlot(QString))/*, Qt::QueuedConnection*/);
 

Адреса объектов будут разными. При этом, если сигнатура будет такой:

Код
C++ (Qt)
private slots:
   void someSlot(QString);
signals:
   void someSignal(QString str);
 

То в обоих случаях в слоте someSlot() qDebug() выведет разные адреса. При Qt::DirectConnect другой адрес потому, что параметр передается не по ссылка, а по значению, а во втором случае потому, что Qt копирует объект, чтобы поместить его в очередь событий.

И для обоих вариантов сигнатура подключения одна и та же:

Код
C++ (Qt)
QObject::connect(this, SIGNAL(someSignal(QString)), SLOT(someSlot(QString)));
 

Но Qt это сама "разруливает". А такое уже не прокатит:

Код
C++ (Qt)
signals:
   void someSignal(const QString& str);
   void someSignal(QString str);
 

Причем еще на этапе компиляции. В C++ невозможно перегрузить метод принимающий параметр одного и того же типа, но с разным способом его передачи (по ссылке или по значению).


Название: Re: сигналы Combobox
Отправлено: BRE от Март 08, 2010, 14:21
При этом, если сигнатура будет такой:

Код
C++ (Qt)
private slots:
   void someSlot(QString);
signals:
   void someSignal(QString str);
 

То в обоих случаях в слоте someSlot() qDebug() выведет разные адреса.
Вот-вот.
Даже при прямом подключении будет происходить копирование объекта. Для чего?

А еще в некоторых случаях, я могу захотеть сделать следующее:
Код
C++ (Qt)
signals:
void getData( QString &data );
 
...
 
void Obj::formData()
{
QString str;
emit getData( str );
 
if( !str.isEmpty() )
useData( str );
}
 

Но Qt это сама "разруливает". А такое уже не прокатит:
Код
C++ (Qt)
signals:
   void someSignal(const QString& str);
   void someSignal(QString str);
 
Причем еще на этапе компиляции. Это что же получается, в C++ невозможно перегрузить метод принимающий параметр одного и того же типа, но с разным способом его передачи?
Не возможно.


Название: Re: сигналы Combobox
Отправлено: SABROG от Март 08, 2010, 14:25
Вот-вот.
Даже при прямом подключении будет происходить копирование объекта. Для чего?

Если в сигнатуре сигнала явно указана передача по ссылке, то копирование объекта будет только в случае Qt::QueuedConnection (ну или между потоками, что тоже самое). А если параметр передается по значению, то там и так понятно, это просто фишка C++. Просто для connect нет никакой разницы как ты передаешь по значению или по ссылке, скорее всего это закадровая работа moc'a.

Код
C++ (Qt)
А еще в некоторых случаях, я могу захотеть сделать следующее:
 

Тогда это:

Код
C++ (Qt)
QObject::connect(this, SIGNAL(someSignal(QString)), SLOT(someSlot(QString))/*, Qt::QueuedConnection*/);
 

Придется менять на это:

Код
C++ (Qt)
QObject::connect(this, SIGNAL(someSignal(QString&)), SLOT(someSlot(QString&))/*, Qt::QueuedConnection*/);
 

Иначе:

Код:
Object::connect: No such signal MainWindow::someSignal(QString)

То есть безболезненно можно менять только константные ссылки. Но при попытке такое провернуть через Qt::QueuedConnection получим:

Код:
QObject::connect: Cannot queue arguments of type 'QString&'
(Make sure 'QString&' is registered using qRegisterMetaType().)


Название: Re: сигналы Combobox
Отправлено: BRE от Март 08, 2010, 14:32
Просто для connect нет никакой разницы как ты передаешь по значению или по ссылке, скорее всего это закадровая работа moc'a.
Для connect нет разницы, он работает с сигнатурами. Но если кто-то вслед за упрощением сигнатур, начнет упрощать объявления самих методов, то он может получить дополнительные тормоза из-за того же копирования аргументов.


Название: Re: сигналы Combobox
Отправлено: SABROG от Март 08, 2010, 14:40
Для connect нет разницы, он работает с сигнатурами.
Разницы нет только в случае с константными ссылками.

Можно конечно утилиту заюзать (http://qt.gitorious.org/qt/qt/trees/master/util/normalize), если не уверен в том, что делаешь (она кстати не распространяется в публичных архивах с исходниками Qt). Потом пару раз глянуть на то, что получается и уже самому вручную это делать.


Название: Re: сигналы Combobox
Отправлено: BRE от Март 08, 2010, 14:49
Можно конечно утилиту заюзать (http://qt.gitorious.org/qt/qt/trees/master/util/normalize), если не уверен в том, что делаешь (она кстати не распространяется в публичных архивах с исходниками Qt). Потом пару раз глянуть на то, что получается и уже самому вручную это делать.
Какое то ускорение работы connect конечно будет. Только, в большинстве случаев, само соединение происходит значительно реже чем вызов самого слота в процессе работы. А я уже привык, что написание аргументов в сигнале, должно совпадать с написанием аргументов в слоте и connect. И визуально это легко проверяется.
Поэтому, мне сейчас будет лениво, отдельно контролировать, что в слоте у меня const Data &, а в connect желательно писать просто Data, что бы упростить работу connect'у.
 :)


Название: Re: сигналы Combobox
Отправлено: SABROG от Март 08, 2010, 15:15
Как правило смысл есть только если создается библиотека или плагин на основе Qt. Разработчик же никогда не знает каким образом будут использовать его библиотеку. Его задача обеспечить максимальное быстродействие при любой ситуации. Вообще я не помню, чтобы мне встречались примеры, где не константная ссылка используется в сигналах. Классы-обертки над указателями - да. Поэтому наверняка случай SIGNAL(MyClass) будет самым распространенным.


Название: Re: сигналы Combobox
Отправлено: waster от Март 08, 2010, 16:59
Посмотри, может быть принимающий объект не унаследован от QObject. Иногда нужно сделать make clean или даже make distclean, и заново qmake && make, несмотря на наличие наследования в коде: такое иногда случается, если объект изначально не имел QObject-предков, потом их добавили, а объектники в силу каких-то причин остались старые (хотя так быть не должно).

Ещё попробуй переписать все connect'ы так, чтобы не было ui.comboBox, а были только прямые объекты и инициализация соединений внутри функций-членов класса, а не снаружи (для этого придётся унаследовать comboBox и создать ему что-то вроде функции setupSignals) - я сталкивался с вариантами, когда снаружи не работало, и кстати, это в любом случае нарушение инкапсуляции.

Но первым делом конечно, нужно запустить программу из командной строки и посмотреть, не ругается ли сама Qt на это соединение.

На тему как писать коннекты: пробелы лучше не ставить, но в любом случае надо писать всё в одном стиле, т.к. есть возможность потом пропарсить соединения, и они будут мешаться.


Название: Re: сигналы Combobox
Отправлено: SABROG от Март 08, 2010, 17:37
Ещё попробуй переписать все connect'ы так, чтобы не было ui.comboBox, а были только прямые объекты
Разницы не будет, moc'у нужны только внутренности SIGNAL()/SLOT(). Недавно обфускатором по коду прошелся, всё в лапшу превратил, кроме токенов SIGNAL()/SLOT() и того, что в скобках, ибо без них moc генерит ерунду.

и инициализация соединений внутри функций-членов класса, а не снаружи (для этого придётся унаследовать comboBox и создать ему что-то вроде функции setupSignals) - я сталкивался с вариантами, когда снаружи не работало, и кстати, это в любом случае нарушение инкапсуляции.
Вы каждый класс на базе QObject'a наследуете, чтобы не нарушать инкапсуляцию? Несмотря на то, что метод QObject::connect() статический, а класс QMetaObject вообще отдельная сущность от QObject'a, связь только через указатель.

На тему как писать коннекты: пробелы лучше не ставить, но в любом случае надо писать всё в одном стиле, т.к. есть возможность потом пропарсить соединения, и они будут мешаться.
В одном стиле с кем, с всемирным сообществом программистов Qt? В каком именно из стилей? Что означает слово "пропарсить", натравить утилиту normalize? И какие именно виды соединений будут мешаться, для пользователя это будет заметно?


Название: Re: сигналы Combobox
Отправлено: waster от Март 08, 2010, 17:43
Ещё попробуй переписать все connect'ы так, чтобы не было ui.comboBox, а были только прямые объекты
Разницы не будет, moc'у нужны только внутренности SIGNAL()/SLOT(). Недавно обфускатором по коду прошелся, всё в лапшу превратил, кроме токенов SIGNAL()/SLOT() и того, что в скобках, ибо без них moc генерит ерунду.

и инициализация соединений внутри функций-членов класса, а не снаружи (для этого придётся унаследовать comboBox и создать ему что-то вроде функции setupSignals) - я сталкивался с вариантами, когда снаружи не работало, и кстати, это в любом случае нарушение инкапсуляции.
Вы каждый класс на базе QObject'a наследуете, чтобы не нарушать инкапсуляцию? Несмотря на то, что метод QObject::connect() статический, а класс QMetaObject вообще отдельная сущность от QObject'a, связь только через указатель.

На тему как писать коннекты: пробелы лучше не ставить, но в любом случае надо писать всё в одном стиле, т.к. есть возможность потом пропарсить соединения, и они будут мешаться.
В одном стиле с кем, с всемирным сообществом программистов Qt? В каком именно из стилей? Что означает слово "пропарсить", натравить утилиту normalize? И какие именно виды соединений будут мешаться, для пользователя это будет заметно?

Тем не менее, пересборка проекта с очисткой объектников помогала в паре подобных случаев.

---

Да, каждый. Просто у меня 95% классов - кастомизируемые. Сначала не переопределял, а потом набрал статистику и понял, что для всех кастомизируемых виджетов удобнее это делать сразу, т.к. придётся всё-равно.

---

С собой, конечно :)

Представь особо умного программера из твоего team-а, который запустит grep на объекты из всех коннектов, не игнорирующий пробелы, и найдёт среднестатистическую половину...


Название: Re: сигналы Combobox
Отправлено: SABROG от Март 08, 2010, 18:07
Да, каждый. Просто у меня 95% классов - кастомизируемые. Сначала не переопределял, а потом набрал статистику и понял, что для всех кастомизируемых виджетов удобнее это делать сразу, т.к. придётся всё-равно.
Я так понимаю, что Вы унаследовали 95% всех виджетов Qt для своего проекта и переопределили paintEvent()? У вас вообще дизайнер не используется ни в каком виде? В слепую пишите интерфейс или сделали плагины для дизайнера на основе собственных классов?

Представь особо умного программера из твоего team-а, который запустит grep на объекты из всех коннектов, не игнорирующий пробелы, и найдёт среднестатистическую половину...

Особо умных программеров везде хватает, подстраиваться всем приходится под клиента, а уж удобно поддерживать нам проект или нет их не волнует, лишь бы работало, стабильно и быстро на сколько это вообще возможно.


Название: Re: сигналы Combobox
Отправлено: garryHotDog от Март 10, 2010, 18:57
Код:
connect(ui.comboBox1,SIGNAL(currentIndexChanged(int)),this,SLOT (slot_SimpleSlot(int)));
У меня работает!!!!


Название: Re: сигналы Combobox
Отправлено: SABROG от Март 10, 2010, 20:51
Надеюсь вызов слота slot_SimpleSlot() в момент запуска программы это то, что вам надо, так как сигнал currentIndexChanged() приходит сразу же как только запуститься программа. Если нужна реакция именно на выбор пользователя, то лучше использовать activated().