Alexander
Alexander7 марта 2020 г. 13:23

Организация передачи данных из сигнала в слот

Доброго времени суток.

Вопрос такого плана. Допустим есть Класс логики "SWCore" и класс GUI "GUICore"
В логике во время какого то действия "происходит" сообщения ("new connections") или на подобие, в целях пример важно что данные QString. Дальше на форме GUICore есть элемент типа QTextEdit. У него есть метод append (который добавляет текст на виджет) Так вот как бы мне написать конеект с передачей этих самых данных. Код для наглядности:


struct Clients{
    int idClient;
    QTcpSocket *TcpSocket;
    QString nameClient;
};

class SoftWareCore : public QObject
{
    Q_OBJECT
public:
    SoftWareCore();
    QVector<Clients> getClientsList() const;
    void setClientsList(const QVector<Clients> &value);

public slots:
    void slotNewConnection();
    void slotServerRead();
    void slotClientDisconnected();
signals:
    void newMsgServ(QString msg);
private:
    Clients cl;
    QVector <Clients> clientsList;
    int countClients;
    QTcpServer * mTcpServer;
    QTcpSocket * mTcpSocket;
};
class GUICore : public QMainWindow
{
    Q_OBJECT
public:
    GUICore(QWidget *parent = nullptr);
    ~GUICore();
private slots:
    void addToPlaneText(QString msg);
private:
    Ui::GUICore *ui;
    SoftWareCore *SWC;
};
void GUICore::addToPlaneText(QString msg)
{
    ui->textEdit->append(msg);
}

вот прям совсем не доганю как должен выглядить коннект

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

28
Docent
  • 7 марта 2020 г. 14:32
  • Ответ был помечен как решение.

создаете signal mysign(QString);
В нужное время emit mysign("text");
Ну и коннект connect(class1, SIGNAL(mysign(QString)), class2.textEdit, SLOT(append(QStting)));

    Alexander
    • 7 марта 2020 г. 14:56

    Спасибо

      Алексей Внуков
      • 7 марта 2020 г. 17:32

      так же конекты отлично поддерживают лямбда-функции, так же хочу обрать внимание на то что коннект типа connect(class1, SIGNAL(mysign(QString)), class2.textEdit, SLOT(append(QStting))) - это старый стиль, и Qt рекомендует использовать только новый стиль
      connect(class1, &Class1::signal, class2,&Class2::func_slot);

        Alexander
        • 8 марта 2020 г. 12:58

        А такой вопрос не черевато что в коннектох использую this без явного указания?

          Evgenii Legotckoi
          • 8 марта 2020 г. 13:23

          Что вы понимаете под явным указанием? this указывает в классе сам на себя, то есть на объект класса внутри себя, это тоже самое, что указывать имя объекта в сигнал слотовое соединение (грубо говоря, поскольку this эквивалентно указателю), так что разницы нет.

            Alexander
            • 9 марта 2020 г. 15:26

            Я понимаю под явным указанием такую запись

                connect (swc,   &SWCore::alive,           this,   &GUICore::isAlive);
                connect (swc,   &SWCore::newMsgServ,      this,   &GUICore::addToPlaneText);
                connect (swc,   &SWCore::newClient,       this,   &GUICore::newConnectionClient);
                connect (swc,   &SWCore::disconectClients,this,   &GUICore::deleteConnectionClient);
            

            тоесть в данном примере swc, но так эти конекты пишутся в конструкторе GUICore то явно уцказать его не получается, только this. Так как помню с js указатель this является не безопасным, вот и интересуюсь не является ли он (this) тоже не совсем безопасным в cpp

              Evgenii Legotckoi
              • 9 марта 2020 г. 15:52

              В случае с this предполагается, что объект существует, по крайней мере на момент передачи указателя this во время выполнения кода.
              Но естественно, если передать объект через this в какую-нибудь функцию или метод другого объекта, а потом в ходе выполнения кода объект, указатель this которого передавался в другой объект, будет удалён, но при этом указатель останется во втором объекте, то в ходе выполнения алгоритма программы можно получить падение программы. То есть указатель this , как впрочем и указатель объекта swc одинаково небезопасны, они равноценно небезопасны. Но в случае с connect методом всё гораздо проще, при уничтожении объектов сигнал-слотовое соединение разрушается автоматически, это обеспечивается архитектурой Qt фреймворка. Так что тут проблем нет.

                Evgenii Legotckoi
                • 9 марта 2020 г. 15:54
                • (ред.)

                Если коротко, то в C++ this - это указатель объекта на самого себя внутри класса, работает абсолютно так же, как и любой другой указатель на объект, например swc в вашем примере. Так что их уровень безопасноти одинаков.

                  Alexander
                  • 9 марта 2020 г. 17:53

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

                    Evgenii Legotckoi
                    • 9 марта 2020 г. 18:14
                    • (ред.)

                    Нет, не совсем. Сигнал-слотовые соединения могут запускать потоко-безопасно методы объектов, которые находятся в других потоках. Но если сигнал и слот находятся в одном потоке, то вызов сигнала запускает выполнение всех слотов, которые привязаны к сигналу, и пока не выполнятся все слоты, то выполнение программы дальше места вызова сигнала не пойдёт. При этом в Qt присутствует очередь вызовов слотов, это было сделано для реализации многопоточности. Таким образом все вызовы слотов с разных потоков ставятся в очередь и выполняются поочерёдно. Поэтому они и считаются потокобезопасными, хотя конечно мьютексы стоит использовать в слотах, иначе можно угробить данные.

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

                    signals:
                        void signal_1();
                        void signal_2();
                        void signal_3();
                    
                    public slots:
                        void slot_1(); // 1 секунда выполнения
                        void slot_2(); // 500 мс
                        void slot_3(); // 200 мс
                    

                    Допустим, мы где-то сделали подключения этих сигналов и слотов (неважно, где и как делали коннекты).
                    И начинаем их вызывать. Если объекты не находятся в разных потоков, а весь код у нас вертится в GUI-потоке, то есть в главном потоке, то получаем следующую ситуацию.

                    emit signal_2(); // вызывается где-то slot_2() - 500 мс
                    emit signal_1(); // вызывается где-то slot_1() - 1 секунда выполнения
                    emit signal_2(); // вызывается где-то slot_2() - 500 мс
                    emit signal_3(); // вызывается где-то slot_3() - 200 мс
                    

                    Как результат, GUI морозится на 2200 мс,

                    Но если какую-то логику переводить в рабочие потоки, то конечно можно избежать заморозки GUI. Это уже вопрос архитектуры. Так что с помощью сигналов и слотов можно добиться асинхронности, но только, если разбивать выполнение кода на потоки, а не крутить всё внутри главного GUI потока.

                      Alexander
                      • 9 марта 2020 г. 18:34

                      Мда теперь надо выводить мою логику в другой поток что бы не гасить гуй. спасибо еще раз пошел гуглить.

                        Alexander
                        • 9 марта 2020 г. 18:42

                        Ах какая красота. Сейчас почитаем

                          Alexander
                          • 9 марта 2020 г. 19:00

                          да ладно, все так просто? я пол года бегал во круг поток, не мог понять. Большое тебе спасибо мил человек. Тут по любому нужен донат!!!

                            Evgenii Legotckoi
                            • 9 марта 2020 г. 19:07

                            Ну нюансов много в процессе работы с потоками всплывает, тоже самое использование мьютексов. Помимо QThread есть ещё QThreadPool, QtConcurrent, достаточно своих нюансов, а также всё для своей области применения.

                              Alexander
                              • 9 марта 2020 г. 19:20

                              Ну пока длч моих целей достаточно тех 3х ссылок. Я не много переделываю Ваш EchoServer на несколько клиентов и с вещянием сигнала и последующим построением графика на клиенском приложении, так сказать тестовое задание себе в портфолио хочу сделать. )

                                Alexander
                                • 11 марта 2020 г. 6:09

                                А можно ли конектить сигналы со слотами котрые отличаются по сигнатуре? например

                                connect(SClients[idUserSocs],&QTcpSocket::disconnected,this,&SWCore::slotDisClient(socketDescriptor);
                                
                                  Alexander
                                  • 11 марта 2020 г. 6:11

                                  или можно ли как то получить указатель на отправителя сигнала, тоесть класс получает в слот сигнал, можно ли понять кто его отправил?

                                    Evgenii Legotckoi
                                    • 11 марта 2020 г. 6:50
                                    • (ред.)

                                    Лучше покажите сигнатуру отдельно, как объявлено в заголовочном файле.

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

                                    void signal() -> void slot()
                                    void signal(QString) -> void slot(QString)
                                    void signal(QString, QString) -> void slot(QString)
                                    

                                    Такие варианты невозможны

                                    void signal() -> void slot(QString)
                                    void signal(QString) -> void slot(double)
                                    void signal(QString, QString) -> void slot(QString, QString)
                                    

                                    Возможно подключение сигнала к сигналу, правило такое же, как подключение сигнала к слоту

                                    void signal_1() -> void signal_2()
                                    void signal_1(QString) -> void signal_2(QString)
                                    void signal_1(QString, QString) -> void slot_2(QString)
                                    

                                    Варианты с подключением, когда сигнатуры отличаются, можно вырешить через лямбда функции

                                    connect(SClients[idUserSocs], &QTcpSocket::disconnected, this, [this](){ slotDisClient(); });
                                    
                                      Alexander
                                      • 11 марта 2020 г. 7:25

                                      Просто я к чему это, что бы не переопределять сигнал &QTcpSocket::disconnected(), который без агрументов, мне надо понимать какой дискриптер его пораждает, что бы правельно удалить ссылку на него в масиве логики и списке клиентов в гуи

                                        Alexander
                                        • 11 марта 2020 г. 7:27

                                        А с лямбдой идея, сейчас попробую

                                          Evgenii Legotckoi
                                          • 11 марта 2020 г. 7:29

                                          Все классы, которые наследованы от QObject имеют метод sender(), который возвращает указатель на отправителя сигнала. Так что вам просто нужно написать слот с проверкой отправителя.

                                          void SWCore::slotDisClient()
                                          {
                                              QObject* s = sender();
                                          
                                              // Далее сравнить указатель с вектором указателей на объекты, которые могли бы выслать этот сигнал.
                                          }
                                          
                                            Alexander
                                            • 11 марта 2020 г. 7:37

                                            О мерси, кстати по донату нет вариантов на карту а то яндекс деньги нема?

                                              Evgenii Legotckoi
                                              • 11 марта 2020 г. 7:47

                                              на яндекс деньги можно и с карты переслать

                                                Alexander
                                                • 11 марта 2020 г. 9:56

                                                не когда не пробывал, с утра затесьтю

                                                  Alexander
                                                  • 11 марта 2020 г. 14:30

                                                  А в продолжения темы про потоки, а совсем плохо если дочерний процес запустить еще процессы в колличестве 5-6 штук?

                                                    Alexander
                                                    • 11 марта 2020 г. 14:30

                                                    А в продолжения темы про потоки, а совсем плохо если дочерний процес запустить еще процессы в колличестве 5-6 штук?

                                                      Evgenii Legotckoi
                                                      • 12 марта 2020 г. 4:18
                                                      • (ред.)

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

                                                      P/S/ вы не могли бы структурировать вопросы и создавать на них новые темы на форуме, иначе тема уже превращается в сборник оффтопов и лучше будет, чтобы был вопрос и его решение, а не вольное обсуждение всего и вся. Даже это обсуждение уже можно было бы разбить, наверное, на три отдельных вопроса. Как никак это форум, а не чат.

                                                        Комментарии

                                                        Только авторизованные пользователи могут публиковать комментарии.
                                                        Пожалуйста, авторизуйтесь или зарегистрируйтесь
                                                        AD

                                                        C++ - Тест 004. Указатели, Массивы и Циклы

                                                        • Результат:50баллов,
                                                        • Очки рейтинга-4
                                                        m
                                                        • molni99
                                                        • 26 октября 2024 г. 11:37

                                                        C++ - Тест 004. Указатели, Массивы и Циклы

                                                        • Результат:80баллов,
                                                        • Очки рейтинга4
                                                        m
                                                        • molni99
                                                        • 26 октября 2024 г. 11:29

                                                        C++ - Тест 004. Указатели, Массивы и Циклы

                                                        • Результат:20баллов,
                                                        • Очки рейтинга-10
                                                        Последние комментарии
                                                        ИМ
                                                        Игорь Максимов22 ноября 2024 г. 22:51
                                                        Django - Урок 017. Кастомизированная страница авторизации на Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
                                                        Evgenii Legotckoi
                                                        Evgenii Legotckoi1 ноября 2024 г. 0:37
                                                        Django - Урок 064. Как написать расширение для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
                                                        A
                                                        ALO1ZE19 октября 2024 г. 18:19
                                                        Читалка fb3-файлов на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
                                                        ИМ
                                                        Игорь Максимов5 октября 2024 г. 17:51
                                                        Django - Урок 064. Как написать расширение для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
                                                        d
                                                        dblas55 июля 2024 г. 21:02
                                                        QML - Урок 016. База данных SQLite и работа с ней в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
                                                        Сейчас обсуждают на форуме
                                                        Evgenii Legotckoi
                                                        Evgenii Legotckoi25 июня 2024 г. 1:11
                                                        добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
                                                        t
                                                        tonypeachey115 ноября 2024 г. 17:04
                                                        google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
                                                        NSProject
                                                        NSProject4 июня 2022 г. 13:49
                                                        Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
                                                        9
                                                        9Anonim25 октября 2024 г. 19:10
                                                        Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

                                                        Следите за нами в социальных сетях