QT C++子类化QLineEdit时构造函数报未定义引用错误如何解决
问题说明
子类化QLineEdit实现自定义方向键响应逻辑时,编译阶段报链接错误:
undefined reference to "DataLineEdit::DataLineEdit(QWidget*)
目标是用自定义的DataLineEdit替换DataWidget中动态创建的原生QLineEdit实例,其余行为保持和原生控件一致。
相关代码
datalineedit.h
#ifndef DATALINEEDIT_H #define DATALINEEDIT_H #include <QLineEdit> #include <QWidget> class DataLineEdit: public QLineEdit { Q_OBJECT public: explicit DataLineEdit(QWidget *parent = 0); ~DataLineEdit(); protected: void keyPressEvent(QKeyEvent* event); signals: void leftRightOverrideKeyPress(int state); private: }; #endif // CUSTOMLINEEDIT_H
datalineedit.cpp
#include "datalineedit.h" #include<QKeyEvent> DataLineEdit::DataLineEdit(QWidget*parent) : QLineEdit(parent) { } DataLineEdit::~DataLineEdit() { } void DataLineEdit::keyPressEvent(QKeyEvent *event) { if(event->key() == Qt::Key_Left && this->cursorPosition() == 0) { emit leftRightOverrideKeyPress(0); } else if(event->key() == Qt::Key_Right && this->cursorPosition() == 2) { emit leftRightOverrideKeyPress(1); } else { QLineEdit::keyPressEvent(event); } }
datawidget.h
#define DATAWIDGET_H #include <QFile> #include <QFileDialog> #include <QTextStream> #include <QMessageBox> #include <QLineEdit> #include <QObject> #include <QtCore> #include <QtGui> #include <QKeyEvent> #include <QMainWindow> #include "datalineedit.h" extern int focusRow; extern int focusCol; extern int numRows; extern int numBottomRowCols; extern QLineEdit *focusedLineEdit; namespace Ui{ class DataWidget; } class QLineEdit; class QLabel; class DataWidget : public QWidget { Q_OBJECT public: explicit DataWidget(QWidget *parent = 0); ~DataWidget(); QString data; protected: bool eventFilter(QObject *object, QEvent *event); public slots: void focusChanged(QWidget *old, QWidget *now); void arrowKeyNavigation(int state); void on_applyChangePushButton_clicked(); void setData(QString text); QString getData(); private slots: void updateDataGridVisibility(); void on_payloadLineEdit_textChanged(const QString &arg1); void on_savePushButton_clicked(); void on_openPushButton_clicked(); void on_presetComboBox_currentIndexChanged(int index); private: Ui::DataWidget *ui; QString currentFile = ""; }; #endif // DATAWIDGET_H
datawidget.cpp
#include "datawidget.h" #include "datawidget.h" #include "datalineedit.h" #include <QGridLayout> #include <QLineEdit> #include <QGroupBox> #include <QKeyEvent> #include <QIntValidator> int focusRow; int focusCol; int numRows; int numBottomRowCols; QLineEdit *focusedLineEdit; enum key_directions { arrowLeft = 0, arrowRight = 1, arrowUp = 2, arrowDown = 3 }; enum presets { preset1 = 0, preset2 = 1, preset3 = 2, preset4 = 3, preset5 = 4, clean = 5, zeroes = 6 }; DataWidget::DataWidget(QWidget *parent) : QWidget(parent), ui(new Ui::DataWidget) { ui->setupUi(this); this->installEventFilter(this); connect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), this, SLOT(focusChanged(QWidget*,QWidget*))); //payloadLineEdit ui->payloadLineEdit->setValidator(new QIntValidator(0,64, this)); ui->payloadLineEdit->setFixedSize(20,20); ui->payloadLineEdit->setTextMargins(0,0,0,0); //dataGridLayout ui->dataGridLayout->setAlignment(Qt::AlignLeft); ui->dataGridLayout->setAlignment(Qt::AlignTop); for(int i=0; i<4; i++) { for(int j=0; j<16; j++) { DataLineEdit *lineEdit = new DataLineEdit(); lineEdit->setText("00");//set data default lineEdit->setInputMask("Hh");//limit to hex values lineEdit->setFixedSize(20,20); lineEdit->setTextMargins(0,0,0,0); lineEdit->setAlignment(Qt::AlignCenter); lineEdit->setAlignment(Qt::AlignCenter); connect(lineEdit, SIGNAL(leftRightOverrideKeyPress(int)), this, SLOT(arrowKeyNavigation(int))); ui->dataGridLayout->addWidget(lineEdit, i, j); } } updateDataGridVisibility(); } DataWidget::~DataWidget() { delete ui; } void DataWidget::arrowKeyNavigation(int state) { //does something }
错误截图

解决方案
这个错误是典型的Qt MOC(元对象编译器)未正确处理带Q_OBJECT宏的类导致的链接错误,按以下步骤排查修复:
- 确认项目构建配置正确
- 如果使用qmake构建,检查.pro文件中是否已经把
datalineedit.h加入HEADERS列表、datalineedit.cpp加入SOURCES列表,示例配置:QT += core gui widgets TARGET = YourProjectName TEMPLATE = app HEADERS += datalineedit.h datawidget.h SOURCES += datalineedit.cpp datawidget.cpp main.cpp - 如果使用CMake构建,确认
datalineedit.cpp在add_executable/add_library的源文件列表中,且已经正确链接Qt::Widgets模块。
- 如果使用qmake构建,检查.pro文件中是否已经把
- 执行完整清理重编译
新增带Q_OBJECT宏的类后,增量编译通常不会自动触发MOC处理新类,需要先删除整个构建目录(或执行构建系统的clean命令,删除所有moc_.cpp、.o中间文件),重新运行qmake/CMake生成构建配置,再全量编译。 - 修复代码中的低级错误
datalineedit.h末尾的头文件守卫注释错误,将#endif // CUSTOMLINEEDIT_H改为#endif // DATALINEEDIT_H,避免后续维护混淆。datawidget.h开头缺少头文件守卫判断,在第一行#define DATAWIDGET_H前补上#ifndef DATAWIDGET_H,防止头文件重复包含引发异常。datawidget.cpp中重复引入了两次datawidget.h,删除重复的include行。
可选优化
datalineedit.cpp中#include<QKeyEvent>改为#include <QKeyEvent>,符合通用编码规范。- 右箭头判断逻辑
cursorPosition() == 2可以加注释说明是对应2位十六进制输入的最右光标位置,后续修改输入长度时不容易出问题。 - 动态创建
DataLineEdit时建议传入父对象:new DataLineEdit(this),交由Qt对象树管理内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Zachary Hicks
相关产品推荐
相关产品推荐

