Я не могу использовать указатель из QMainWindow в качестве аргумента в соединении для QT5

Этот код создает поток и подключает его к QT.

      void UI_handling::create_thread_for_looping_terminal(){
    loop_terminal_thread = new Loop_terminal_thread(mainWindow, &j1939);
    loop_terminal_thread->start();
    mainWindow->connect(loop_terminal_thread, &Loop_terminal_thread::send_ID_and_data_to_looping_terminal, mainWindow, &MainWindow::update_looping_teriminal);
}

Этот код дает ошибку ->connect часть из-за аргумента.

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

      connect(loop_terminal_thread, &Loop_terminal_thread::send_ID_and_data_to_looping_terminal, this, &MainWindow::update_looping_teriminal);

Так почему mainWindow проблема, если у меня есть конструктор, который выглядит так

      UI_handling::UI_handling(QMainWindow* mainWindow, Ui::MainWindow* ui) : mainWindow(mainWindow), ui(ui){

}

И я называю UI_handling конструктор внутри класса

      #include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow){
    ui->setupUi(this);

    /* Important handler */
    ui_handling = new UI_handling(this, ui);

Итак, почему аргумент this, из-за чего я не понимаю правильного аргумента?

Ошибка:

      ui_handling.cpp:119:17: error: no matching member function for call to 'connect'
qobject.h:242:43: note: candidate function [with Func1 = void (Loop_terminal_thread::*)(unsigned int, unsigned char *), Func2 = void (MainWindow::*)(unsigned int, unsigned char *)] not viable: cannot convert from base class pointer 'QMainWindow *' to derived class pointer 'const typename QtPrivate::FunctionPointer<void (MainWindow::*)(unsigned int, unsigned char *)>::Object *' (aka 'const MainWindow *') for 3rd argument
qobject.h:222:36: note: candidate function not viable: no known conversion from 'void (Loop_terminal_thread::*)(uint32_t, uint8_t *)' to 'const char *' for 2nd argument
qobject.h:225:36: note: candidate function not viable: no known conversion from 'void (Loop_terminal_thread::*)(uint32_t, uint8_t *)' to 'const QMetaMethod' for 2nd argument
qobject.h:481:41: note: candidate function not viable: no known conversion from 'void (Loop_terminal_thread::*)(uint32_t, uint8_t *)' to 'const char *' for 2nd argument
qobject.h:283:13: note: candidate template ignored: requirement '!QtPrivate::FunctionPointer<void (MainWindow::*)(unsigned int, unsigned char *)>::IsPointerToMemberFunction' was not satisfied [with Func1 = void (Loop_terminal_thread::*)(unsigned int, unsigned char *), Func2 = void (MainWindow::*)(unsigned int, unsigned char *)]
qobject.h:322:13: note: candidate template ignored: requirement 'QtPrivate::FunctionPointer<void (MainWindow::*)(unsigned int, unsigned char *)>::ArgumentCount == -1' was not satisfied [with Func1 = void (Loop_terminal_thread::*)(unsigned int, unsigned char *), Func2 = void (MainWindow::*)(unsigned int, unsigned char *)]
qobject.h:274:13: note: candidate function template not viable: requires 3 arguments, but 4 were provided
qobject.h:314:13: note: candidate function template not viable: requires 3 arguments, but 4 were provided

Минимальный пример:

Сначала вы создаете заголовок потока

      #ifndef LOOP_TERMINAL_THREAD_H

#define LOOP_TERMINAL_THREAD_H

#include <QThread>
#include <QObject>

class Loop_terminal_thread : public QThread {
    Q_OBJECT
public:
    Loop_terminal_thread(QObject *parent = nullptr);
signals:
    void send_ID_and_data_to_looping_terminal(uint32_t ID, uint8_t data[]);
private:
    bool* start_loop_terminal_thread;
    void run();
};

#endif // LOOP_TERMINAL_THREAD_H

Затем вы создаете источник потока

      #include "loop_terminal_thread.h"

Loop_terminal_thread::Loop_terminal_thread(QObject *parent) : QThread(parent)  {

}

void Loop_terminal_thread::run(){
    uint8_t data[8] = {0};
    data[1] = 23;
    while(1){
            emit send_ID_and_data_to_looping_terminal(300, data);
        msleep(1000);
    }
}

Затем вы создаете UI_handler класс

      /* QT includes */
#include "ui_mainwindow.h"
#include <QStandardItemModel>
#include <QIntValidator>
#include <QMainWindow>

/* Project includes */
#include "UI_threads/Loop_terminal_thread/loop_terminal_thread.h"

class UI_handling{
public:
    UI_handling(QMainWindow* mainWindow, Ui::MainWindow* ui);
    void create_thread_for_looping_terminal();

private:
    QMainWindow* mainWindow;
    Ui::MainWindow* ui;

    /* Thread for the looping terminal */
    Loop_terminal_thread* loop_terminal_thread;

};

#endif // UI_HANDLING_H

И вы реализуете счетчик и функцию внутри исходного файла.

      UI_handling::UI_handling(QMainWindow* mainWindow, Ui::MainWindow* ui) : mainWindow(mainWindow), ui(ui){

}

void UI_handling::create_thread_for_looping_terminal(){
    loop_terminal_thread = new Loop_terminal_thread(mainWindow, &j1939);
    loop_terminal_thread->start();
    mainWindow->connect(loop_terminal_thread, &Loop_terminal_thread::send_ID_and_data_to_looping_terminal, mainWindow, &MainWindow::update_looping_teriminal);
}

Затем, наконец, вы реализуете это внутри своего конструктора

      MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow){
    ui->setupUi(this);

    /* Important handler */
    ui_handling = new UI_handling(this, ui);
    ui_handling->create_thread_for_looping_terminal();
}

void MainWindow::update_looping_teriminal(uint32_t ID, uint8_t data[]){

}

Заголовочный файл MainWindow класс выглядит так

      QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

public slots:
    void update_looping_teriminal(uint32_t ID, uint8_t data[]);

1 ответ

Подсказка находится в этой части сообщения об ошибке:

      cannot convert from base class pointer 'QMainWindow *'
to derived class pointer ... (aka 'const MainWindow *') for 3rd argument

Вы подключаетесь к слоту в классе, поэтому вам необходимо указать указатель на. Указателя на недостаточно.

Когда вы запускаете соединение внутри и проходите this, то тип этого аргумента - и он работает.

Чтобы ваш код работал, вам нужно изменить UI_handling класс, так что он хранит указатель на MainWindow вместо того QMainWindow.

Другие вопросы по тегам