我不能使用 QMainWindow 的指针作为 QT5 连接中的参数
I cannot use the pointer from QMainWindow as argument in connect for QT5
此代码创建一个线程并将其连接到 QT
中的 MainWindow
。
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
参数,此代码在 ->connect
部分给出错误。
如果我将 运行 这段代码放在 MainWindow
class 中,它将看起来像这样。它会正常工作,但如您所见,mainWindow
是这里的问题。
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){
}
然后我在 MainWindow
class
中调用 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
最小示例:
首先创建线程header
#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
class
/* 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::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
class的header文件如下所示
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[]);
线索在这部分错误信息中:
cannot convert from base class pointer 'QMainWindow *'
to derived class pointer ... (aka 'const MainWindow *') for 3rd argument
您正在连接到 MainWindow
class 中的插槽,因此您需要提供指向 MainWindow
的指针。指向 QMainWindow
的指针是不够的。
当您 运行 在 MainWindow
内连接并传递 this
时,此参数的类型为 MainWindow
并且有效。
为了让您的代码正常工作,您需要更改 UI_handling
class,以便它存储指向 MainWindow
而不是 QMainWindow
.[=20 的指针=]
此代码创建一个线程并将其连接到 QT
中的 MainWindow
。
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
参数,此代码在 ->connect
部分给出错误。
如果我将 运行 这段代码放在 MainWindow
class 中,它将看起来像这样。它会正常工作,但如您所见,mainWindow
是这里的问题。
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){
}
然后我在 MainWindow
class
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
最小示例:
首先创建线程header
#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
class
/* 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::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
class的header文件如下所示
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[]);
线索在这部分错误信息中:
cannot convert from base class pointer 'QMainWindow *'
to derived class pointer ... (aka 'const MainWindow *') for 3rd argument
您正在连接到 MainWindow
class 中的插槽,因此您需要提供指向 MainWindow
的指针。指向 QMainWindow
的指针是不够的。
当您 运行 在 MainWindow
内连接并传递 this
时,此参数的类型为 MainWindow
并且有效。
为了让您的代码正常工作,您需要更改 UI_handling
class,以便它存储指向 MainWindow
而不是 QMainWindow
.[=20 的指针=]