Russian Qt Forum
Ноябрь 24, 2024, 19:41 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Первый вызов сигнала  (Прочитано 4356 раз)
Impuls
Гость
« : Январь 14, 2011, 01:01 »

Доброго времени суток уважаемые эксперты. Для начала хочу извиниться за туманную формулировку названия темы.
Сразу перейду к делу:
Есть класс А, в нем пара: Сигнал->Слот. Эта пара занимается синхронизацией двух объектов, причем объекты являются полями другого класса:
Класс B включает объекты класса А.
При изменении объекта а1, должна произойти некоторая модификация объекта а2, и наоборот. Причем никто не ограничивает количество таких объектов.
А теперь проблема: Сразу после создания (еще до соединения двух объектов), объекты рассинхронизированы и не могут быть сведены в единое целое без сигнала из вне. После соединения, и модификации одного из объектов - происходит синхронизация. А вот меня интересует граничный случай: объекты созданы, соединены, но не модифицированы. Как можно провести их синхронизацию после соединения? Надеюсь вразумительно смог объяснить ситуацию)).
Приведу пример. Он, конечно, надуманный, но суть проблемы отражает:
Код:
class A : QObject
{
Q_OBJECT
public:
void Print();
        A(){
                a1 = rand();};
ModifiA1(int _a1){
a1 = _a1;
emit SignalS(a1);};
signal:
SignalS(int Data);
public slots:
SlotS(int Data){
a2 = Data;};
private:
int a1,a2;
};

class B : QObject
{
Q_OBJECT
public:
B(){
a1 = new A;
a2 = new A;
connect(a1, SIGNAL(SignalS(int)), a2, SLOT(SlotS(int));
connect(a2, SIGNAL(SignalS(int)), a1, SLOT(SlotS(int));};
ModifiA1(int a){
a1.ModifiA1(a);
}
ModifiA2(int a){
a2.ModifiA1(a);
}
private:
A *a1,*a2;
}
Понятно, что после вызова методов ModifiA1 и ModifiA2 - объекты синхронизируются, но до этого объекты не будут дружить друг с дружкой(((
Заранее спасибо.
« Последнее редактирование: Январь 14, 2011, 01:09 от Impuls » Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #1 : Январь 14, 2011, 09:22 »

см. QMetaObject::invokeMethod()
Записан

Qt 5.11/4.8.7 (X11/Win)
Impuls
Гость
« Ответ #2 : Январь 14, 2011, 13:15 »

см. QMetaObject::invokeMethod()
Если я правильно понял QMetaObject::invokeMethod() - вызывает любой сигнал или слот. Но в любом случае мне нужно будет сделать такую конструкцию:
connect()
QMetaObject::invokeMethod()
А я же хотел чтобы сразу после connect автоматически вызывался сигнал, чтобы я дальше не заботился о синхронизации. Такое вообще реально?
Записан
andrew.k
Гость
« Ответ #3 : Январь 14, 2011, 14:18 »

зачем invokeMethod? invokeMethod синхронизирует объекты позже (асинхронно), когда будет запущен евент луп либо когда подойдет очередь события. Поэтому какое-то время объекты будут не синхронизированы.
Такое решение не всегда будет подходить задаче.
Поэтому сразу после коннекта вызови слот напрямую. И все. Что может быть проще?
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #4 : Январь 14, 2011, 14:23 »

Цитата: andrew.k
invokeMethod синхронизирует объекты позже (асинхронно)
Цитировать
The invocation can be either synchronous or asynchronous, depending on type:
If type is Qt::DirectConnection, the member will be invoked immediately.
If type is Qt::QueuedConnection, a QEvent will be sent and the member is invoked as soon as the application enters the main event loop.
If type is Qt::BlockingQueuedConnection, the method will be invoked in the same way as for Qt::QueuedConnection, except that the current thread will block until the event is delivered. Using this connection type to communicate between objects in the same thread will lead to deadlocks.
If type is Qt::AutoConnection, the member is invoked synchronously if obj lives in the same thread as the caller; otherwise it will invoke the member asynchronously.
Записан

Qt 5.11/4.8.7 (X11/Win)
Impuls
Гость
« Ответ #5 : Январь 14, 2011, 15:09 »

Поэтому сразу после коннекта вызови слот напрямую. И все. Что может быть проще?
Все легко. Однако это все лишние телодвижения, про которые можно легко забыть. А это чревато последствиями. Так что лучше: сделать класс и забыть про его реализацию, или все равно забыть про реализацию, а потом натыкаться на таких мелких гаденышей?
Записан
Impuls
Гость
« Ответ #6 : Январь 14, 2011, 17:11 »

Проблема решена QObject::connectNotify - вызывается всякий раз, когда происходит соединение сигналов класса
Вот пример:
Код:
#ifndef QTESTCLASS_H
#define QTESTCLASS_H

#include <QObject>

class QTestClass : public QObject
{
    Q_OBJECT
public:
    explicit QTestClass(QObject *parent = 0);

    void CallSignl(int a);
protected:
    virtual void connectNotify(const char *signal);
signals:
    void TestSignal(int a);
public slots:
    void TestSlot(int a);
};

#endif // QTESTCLASS_H
Код:
#include "QTestClass.h"
#include <iostream>
#include <QLatin1String>

using namespace std;

QTestClass::QTestClass(QObject *parent) : QObject(parent)
{
}
void QTestClass::CallSignl(int a)
{
    emit TestSignal(a);
}
void QTestClass::connectNotify(const char *signal)
{
     if (QLatin1String(signal) == SIGNAL(TestSignal(int))) {
        cout<<"Сигнал был соединен со слотом"<<endl;
     }
}

void QTestClass::TestSlot(int a)
{
    cout<<a<<endl;
}
Код:
#include <QApplication>
#include <QObject>
#include "QTestClass.h"


int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    QTestClass *a = new QTestClass;

    QObject::connect(a, SIGNAL(TestSignal(int)), a, SLOT(TestSlot(int)));
    a->CallSignl(10);
    QObject::connect(a, SIGNAL(TestSignal(int)), a, SLOT(TestSlot(int)));
    a->CallSignl(15);
    return app.exec();
}
Записан
andrew.k
Гость
« Ответ #7 : Январь 15, 2011, 16:48 »

Цитата: andrew.k
invokeMethod синхронизирует объекты позже (асинхронно)
Цитировать
The invocation can be either synchronous or asynchronous, depending on type:
If type is Qt::DirectConnection, the member will be invoked immediately.
If type is Qt::QueuedConnection, a QEvent will be sent and the member is invoked as soon as the application enters the main event loop.
If type is Qt::BlockingQueuedConnection, the method will be invoked in the same way as for Qt::QueuedConnection, except that the current thread will block until the event is delivered. Using this connection type to communicate between objects in the same thread will lead to deadlocks.
If type is Qt::AutoConnection, the member is invoked synchronously if obj lives in the same thread as the caller; otherwise it will invoke the member asynchronously.
Точно, я забыл об этом. только что занимался многопоточкой и там использовал invokeMethod поэтому привык Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.088 секунд. Запросов: 22.