0

I am working on a project that utilizes a whole suite of custom widget that my company uses.

I am trying to subclass the QLineEdit QWidget so that I can override the default arrow key behavior. It should just behave like a regular QLineEdit.

I then want to use this custom QLineEdit (that I named DataLineEdit), in place of the standard QLineEdits that I dynamically created in another Widget, DataWidget.

I have followed tutorial after tutorial on subclassing, but cannot avoid the error:

undefined reference to "DataLineEdit::DataLineEdit(QWidget*)

My code is below.

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
}

screenshot of the error

Marek R
  • 32,568
  • 6
  • 55
  • 140
  • I didn't read your code thoroughly, but the very first thing catching attention is that you incorrectly using the [include guards](https://en.wikipedia.org/wiki/Include_guard#File_%22grandparent.h%22_2). You seem to have forgotten the #ifndef part – absolute.madness Jul 14 '22 at 13:01
  • I apologize, those mistakes were from me testing possible solutions. I have updated the post to have what I believe should be the correct code. – Zachary Hicks Jul 14 '22 at 13:33
  • 1
    That looks like a linker error. You need to make sure `datalineEdit.cpp` is getting compiled and the object file is being linked with everything else. BTW, your capitalization is an inconsistent mess. Choose a style, and stick with it - either `datalineedit.h` or `DataLineEdit.cpp`, don't just hit SHIFT at random while typing. – Useless Jul 14 '22 at 13:37
  • You may be missing `datalineedit.cpp` (and probably also `datalineedit.h`) in your `CMakeLists.txt` file if you are using CMake or `.pro` file, if you are using QMake. – HiFile.app - best file manager Jul 14 '22 at 14:08
  • Is your DataWidget in an own dll and you're on windows? If so you must properly export the class -> https://doc.qt.io/qt-6/sharedlibrary.html – chehrlic Jul 14 '22 at 14:43
  • Please don't use pictures of text, so it can be searched (hint!) conveniently. Also, first thing you should do is to extract a [mcve]. Things like the messed up include guards don't happen then. Also, your title gives no indication what the problem is, it is just a a (usually flawed) interpretation. Please, as a new user here, take the [tour] and read [ask] as well. – Ulrich Eckhardt Jul 14 '22 at 15:44
  • `undefined reference to "DataLineEdit::DataLineEdit(QWidget*)` error with code provided means that your build process is broken and `datalineedit.cpp` in not compiled or linked to final target. – Marek R Jul 14 '22 at 15:50

2 Answers2

0

You could edit the class in the following form:

class DataLineEdit: public QLineEdit
{
    Q_OBJECT
    public:
    explicit DataLineEdit(QWidget* parent = 0);
...

and

DataLineEdit::DataLineEdit(QWidget* parent) : QLineEdit(parent)
{

}
ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
0

Thank you for all the help, it was definitely a linker issue but since I am working within a much larger project, I didn't want to mess with imports or .pro files too much. DataLineEdit is specific to DataWidget, so I simply moved the entire datalineedit.h file into the datawidget.h file at the bottom, and the same for the .cpp files. This avoids any linking all together and keeps things tidier based on the project's file hierarchy.