QT传递Ui::MainWindow*作为参数后无法通过ui->访问成员的原因
错误原因
你遇到的是C++前向声明的典型问题:
- 在
mainwindow.h中仅对Ui::MainWindow做了前向声明(namespace Ui { class MainWindow; }),没有给出类的完整定义,编译器此时仅知道该类存在,无法获知它的成员结构、成员函数等信息。 - 你的
database.h引入了mainwindow.h,但也只能拿到Ui::MainWindow的前向声明。Ui::MainWindow的完整定义由Qt的uic工具自动生成,保存在编译输出的ui_mainwindow.h文件中,你没有在database.cpp中引入这个文件,所以编译Database::connect函数时,编译器无法识别ui指针指向的类有哪些成员,就会抛出「访问不完整类型」的错误。 - 指针传递本身是合法的:C++中只要有前向声明,就可以定义对应类的指针、传递指针,但只要涉及访问类的成员,就必须要有类的完整定义。
解决方法
提供两种可选方案,第二种更符合代码分层设计规范:
方案1:补充头文件引入
直接在database.cpp的头部引入Qt生成的UI头文件即可:
#include "ui_mainwindow.h"
这样编译database.cpp时编译器就能拿到Ui::MainWindow的完整定义,正常访问控件成员。
方案2:解耦UI层和数据层(更推荐)
Database类属于数据层,不应该直接依赖UI层的类,你可以修改Database::connect的入参,直接接收数据库连接需要的参数,而不是传入UI指针:
- 修改Database类的头文件声明:
// database.h中修改connect声明 void connect(const QString& host, int port, const QString& dbName, const QString& username, const QString& password);
- 在MainWindow的槽函数中提前读取UI控件的值,再传入connect方法:
void MainWindow::on_connect_sql_pushButton_clicked(){ QString host = ui->sql_host_lineEdit->text(); int port = ui->sql_port_lineEdit->text().toInt(); QString dbName = ui->sql_database_lineEdit->text(); QString username = ui->sql_username_lineEdit->text(); QString password = ui->sql_password_lineEdit->text(); database.connect(host, port, dbName, username, password); }
- 调整
Database::connect的实现,直接用传入的参数设置连接即可,不用再访问UI成员。
内容的提问来源于stack exchange,提问作者euraad
相关产品推荐
相关产品推荐

