QLineEdit lostFocus problem



  • Hi,
    i've to create an App to calculate tools data for CNC Machine
    Now for Desktop and later for Android.

    0_1565779967785_Schermata 2019-08-14 alle 12.52.31.png

    i have to know when LineEdit lost Focus in order to do some operations
    (using numeric keyboard i have to insert to the MyLineEdit who lost focus and ...)

    to do this i've subclassed QLineEdit class:

    class MyLineEdit : public QLineEdit
    {
        Q_OBJECT
    public:
        MyLineEdit(QWidget *parent = nullptr) : QLineEdit(parent){}
    protected:
        void focusOutEvent(QFocusEvent *event)
        {
           QLineEdit::focusOutEvent(event);
           QWidget * widgetName = qApp->focusWidget();
           Target = widgetName->objectName(); //<- to identify MyLineEdit who lost focus 
            if(!hasAcceptableInput())
            {
                setFocus();
            }
    
        }
    signals:
    };
    

    my problem is when i try to add MyLineEdit to QGridLayout:

     QGridLayout *mainLayout = new QGridLayout;
        //mainLayout->setAlignment(Qt::AlignCenter);
        mainLayout->addWidget(LFresatura, 0, 0, 1, 2);
        mainLayout->setSizeConstraint(QLayout::SetFixedSize);
        mainLayout->addWidget(LDiametro, 1, 0);
        mainLayout->addWidget(Diametro, 1, 1);
        mainLayout->addWidget(LVelTaglio, 2, 0);
        mainLayout->addWidget(VelTaglio, 2, 1);
        mainLayout->addWidget(LGiriMandrino, 3, 0);
        mainLayout->addWidget(GiriMandrino, 3, 1);
        mainLayout->addWidget(LNDenti, 4, 0);
        mainLayout->addWidget(NDenti, 4, 1);
        mainLayout->addWidget(LAvDente, 5, 0);
        mainLayout->addWidget(AvDente, 5, 1);
        mainLayout->addWidget(LAvanzamento, 6, 0);
        mainLayout->addWidget(Avanzamento, 6, 1);
        this->setLayout(mainLayout);
    

    Application crashes..
    I can't understand why.. Someone can help me please??

    I suppose that no initialization can give problem but if i try to initialize with "0"
    give me this error :

    error: cannot initialize a variable of type 'MyLineEdit *' with an lvalue of type 'const char [1]'

    this is declaration of Diametro:

    MyLineEdit *Diametro;
    

  • Moderators

    @thecipo76

    if this
    MyLineEdit *Diametro;

    if everything in your code, than you only have a pointer but no instance.

    MyLineEdit *Diametro = new MyLineEdit();
    


  • @j-hilk said in QLineEdit lostFocus problem:

    MyLineEdit *Diametro = new MyLineEdit()

    i've tried but gave me this:

    symbol(s) not found for architecture x86_64
    linker command failed with exit code 1 (use -v to see invocation)


  • Moderators

    @thecipo76
    that's a bit difficult to debug with just that information.

    a couple of things to check:

    • did you include MyLineEdit.h
    • as a header only class do you still have a .cpp file in your project
    • switch to the compiler output tab, the error there should provide more information


  • @j-hilk i've put MyLineEdit class directly in .cpp file
    to keep Target value

    this is Compile Output

    Undefined symbols for architecture x86_64:
    "vtable for MyLineEdit", referenced from:
    MyLineEdit::MyLineEdit(QWidget*) in fresatura.o
    NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    make: *** [CNCMaster.app/Contents/MacOS/CNCMaster] Error 1
    13:25:08: The process "/usr/bin/make" exited with code 2.
    Error while building/deploying project CNCMaster (kit: Desktop Qt 5.13.0 clang 64bit)
    When executing step "Make"



  • @j-hilk i've tried to put MyLineEdit class to .h file like explained here

    https://lizardo.wordpress.com/2009/04/24/undefined-reference-to-vtable-for-errors-in-qt-derived-classes/

    but

    i have this:

    use of undeclared identifier qApp

    on this line

    QWidget * widgetName = qApp->focusWidget();
    


  • did you
    #include <QApplication>



  • @eddy said in QLineEdit lostFocus problem:

    #include <QApplication>

    you're right .. i forgot it

    but now i have this:

    duplicate symbol _Target in:
    fresatura.o
    mainwindow.o
    duplicate symbol _Target in:
    fresatura.o
    moc_fresatura.o
    ld: 2 duplicate symbols for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    make: *** [CNCMaster.app/Contents/MacOS/CNCMaster] Error 1
    14:06:25: The process "/usr/bin/make" exited with code 2.
    Error while building/deploying project CNCMaster (kit: Desktop Qt 5.13.0 clang 64bit)
    When executing step "Make"



  • search your project for "Target"
    the compiler tells you you have defined it twice

    EDIT: look in the pro file also



  • @eddy

    0_1565786150100_Schermata 2019-08-14 alle 14.30.39.png

    EDIT: can TARGET in pro file give duplicate??
    it's better change name??



  • I would not expect it.

    But anyway is it possible to upload a small compilable example. We're guessing all the time what could be wrong in your application.



  • @eddy
    main.cpp

    #include "mainwindow.h"
    #include <QApplication>
    #include <QFont>
    
    
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        QFont V = QFont ("Verdana", 16);
        QApplication::setFont(V);
        w.showMaximized();
    
    
    
        return a.exec();
    }
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "fresatura.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::on_pushButton_Esci_clicked()
    {
        close();
    }
    
    void MainWindow::on_pushButton_Fresatura_clicked()
    {
        //FRESATURA
        fresatura Fresatura;
        Fresatura.setModal(true);
        Fresatura.exec();
    
    }
    
    

    fresatura.h

    #ifndef FRESATURA_H
    #define FRESATURA_H
    
    #include <QDialog>
    #include <QLineEdit>
    #include <QLabel>
    #include <QPushButton>
    #include <QWidget>
    #include <QApplication>
    
    QString Target;
    
    class MyLineEdit : public QLineEdit
    {
        Q_OBJECT
    public:
        MyLineEdit(QWidget *parent = nullptr) : QLineEdit(parent){}
    protected:
        void focusOutEvent(QFocusEvent *event)
        {
           QLineEdit::focusOutEvent(event);
           QWidget * widgetName = qApp->focusWidget();
           Target = widgetName->objectName();
    
            if(!hasAcceptableInput())
            {
                setFocus();
            }
    
        }
    signals:
    };
    
    namespace Ui {
    class fresatura;
    }
    
    class fresatura : public QDialog
    {
        Q_OBJECT
    
    public:
        explicit fresatura(QWidget *parent = nullptr);
        ~fresatura();
    
    private slots:
    
    
    private:
        //Label
        QLabel *LFresatura;
        QLabel *LDiametro;
        QLabel *LVelTaglio;
        QLabel *LGiriMandrino;
        QLabel *LNDenti;
        QLabel *LAvDente;
        QLabel *LAvanzamento;
        //LineEdit
        //QLineEdit *Diametro;
        QLineEdit *VelTaglio;
        QLineEdit *GiriMandrino;
        QLineEdit *NDenti;
        QLineEdit *AvDente;
        QLineEdit *Avanzamento;
        //PushButton
        QPushButton *Zero;
        QPushButton *Uno;
        QPushButton *Due;
        QPushButton *Tre;
        QPushButton *Quattro;
        QPushButton *Cinque;
        QPushButton *Sei;
        QPushButton *Sette;
        QPushButton *Otto;
        QPushButton *Nove;
        //QPushButton *BS;
        //QPushButton *Punto;
    
        QPushButton *Esci;
    
        Ui::fresatura *ui;
    };
    
    #endif // FRESATURA_H
    

    fresatura.cpp

    #include "fresatura.h"
    #include "ui_fresatura.h"
    #include <QIntValidator>
    #include <QDoubleValidator>
    #include <QGridLayout>
    #include <QFont>
    #include <QMessageBox>
    
    
    fresatura::fresatura(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::fresatura)
    {
        ui->setupUi(this);
    
        this->showMaximized();
        this->setFixedSize(1080, 1920);
        QFont V16 = QFont ("Verdana", 16);
        QFont VT = QFont ("Verdana", 34);
        this->setFont(V16);
    
        LFresatura = new QLabel(" F  R  E  S  A  T  U  R  A");
        LFresatura->setFont(VT);
    
        LDiametro = new QLabel("Diametro Fresa:");
        LVelTaglio = new QLabel("Velocità di Taglio:");
        LGiriMandrino = new QLabel("Giri Mandrino:");
        LNDenti = new QLabel("N. Denti Fresa:");
        LAvDente = new QLabel("Avanzam./Dente:");
        LAvanzamento = new QLabel("Avanzam. mm/min:");
    
        MyLineEdit *Diametro = new MyLineEdit();
        Diametro->setAlignment(Qt::AlignRight);
        Diametro->setValidator(new QIntValidator(1, 100, this));
    
        VelTaglio = new QLineEdit("");
        VelTaglio->setAlignment(Qt::AlignRight);
        VelTaglio->setValidator(new QIntValidator(1, 300, this));
    
        GiriMandrino = new QLineEdit("");
        GiriMandrino->setAlignment(Qt::AlignRight);
        GiriMandrino->setReadOnly(true);
    
        NDenti = new QLineEdit("");
        NDenti->setAlignment(Qt::AlignRight);
        NDenti->setValidator(new QIntValidator(1, 10, this));
    
        AvDente = new QLineEdit("");
        AvDente->setAlignment(Qt::AlignRight);
        AvDente->setValidator(new QDoubleValidator(0, 10, 2, this));
    
        Avanzamento = new QLineEdit("");
        Avanzamento->setAlignment(Qt::AlignRight);
        Avanzamento->setReadOnly(true);
    
        //KeyBoard
        Zero = new QPushButton;
        Zero->setText("0");
        Uno = new QPushButton;
        Uno->setText("1");
        Due = new QPushButton;
        Due->setText("2");
        Tre = new QPushButton;
        Tre->setText("3");
        Quattro = new QPushButton;
        Quattro->setText("4");
        Cinque = new QPushButton;
        Cinque->setText("5");
        Sei = new QPushButton;
        Sei->setText("6");
        Sette = new QPushButton;
        Sette->setText("7");
        Otto = new QPushButton;
        Otto->setText("8");
        Nove= new QPushButton;
        Nove->setText("9");
        QGridLayout *mainLayout = new QGridLayout;
        //mainLayout->setAlignment(Qt::AlignCenter);
        mainLayout->addWidget(LFresatura, 0, 0, 1, 2);
        mainLayout->setSizeConstraint(QLayout::SetFixedSize);
        mainLayout->addWidget(LDiametro, 1, 0);
        mainLayout->addWidget(Diametro, 1, 1);
        mainLayout->addWidget(LVelTaglio, 2, 0);
        mainLayout->addWidget(VelTaglio, 2, 1);
        mainLayout->addWidget(LGiriMandrino, 3, 0);
        mainLayout->addWidget(GiriMandrino, 3, 1);
        mainLayout->addWidget(LNDenti, 4, 0);
        mainLayout->addWidget(NDenti, 4, 1);
        mainLayout->addWidget(LAvDente, 5, 0);
        mainLayout->addWidget(AvDente, 5, 1);
        mainLayout->addWidget(LAvanzamento, 6, 0);
        mainLayout->addWidget(Avanzamento, 6, 1);
    
        mainLayout->addWidget(Uno, 7, 0);
        mainLayout->addWidget(Due, 7, 1);
        mainLayout->addWidget(Tre, 7, 2);
        mainLayout->addWidget(Quattro, 8, 0);
        mainLayout->addWidget(Cinque, 8, 1);
        mainLayout->addWidget(Sei, 8, 2);
        mainLayout->addWidget(Sette, 9, 0);
        mainLayout->addWidget(Otto, 9, 1);
        mainLayout->addWidget(Nove, 9, 2);
        this->setLayout(mainLayout);
    
    }
    
    
    
    fresatura::~fresatura()
    {
        delete ui;
    }
    
    

    Pro File:

    #-------------------------------------------------
    #
    # Project created by QtCreator 2019-08-08T13:35:11
    #
    #-------------------------------------------------
    
    QT       += core gui
    
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    TARGET = CNCMaster
    TEMPLATE = app
    
    # The following define makes your compiler emit warnings if you use
    # any feature of Qt which has been marked as deprecated (the exact warnings
    # depend on your compiler). Please consult the documentation of the
    # deprecated API in order to know how to port your code away from it.
    DEFINES += QT_DEPRECATED_WARNINGS
    
    # You can also make your code fail to compile if you use deprecated APIs.
    # In order to do so, uncomment the following line.
    # You can also select to disable deprecated APIs only up to a certain version of Qt.
    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    
    CONFIG += c++11
    
    SOURCES += \
            fresatura.cpp \
            main.cpp \
            mainwindow.cpp
    
    HEADERS += \
            fresatura.h \
            mainwindow.h
    
    FORMS += \
            fresatura.ui \
            mainwindow.ui
    
    CONFIG += mobility
    MOBILITY = 
    
    
    # Default rules for deployment.
    qnx: target.path = /tmp/$${TARGET}/bin
    else: unix:!android: target.path = /opt/$${TARGET}/bin
    !isEmpty(target.path): INSTALLS += target
    
    RESOURCES += \
        resource.qrc
    
    


  • at first glance I can see in your pro file:
    MOBILITY =



  • @eddy said in QLineEdit lostFocus problem:

    at first glance I can see in your pro file

    yes because i will try it as for Desktop and Android too



  • You cannot put a line without putting something behind MOBILITY
    like
    MOBILITY += sensors
    What is it you want to do here?

    I recommend when looking at your code to make it work first on desktop before even thinking on using it on Android.
    Comment that line for now and look in Qt Creator at all the lines with errors. Solve one at a time...you cannot let lines open or ignore warnings from the compiler.



  • @eddy I've started to load it to my smartphone (Android) then i've decided to try before on my mac..

    i haven't put this lines:

    CONFIG += mobility
    MOBILITY =
    

    in the pro file..

    now i've comment it with #

    the only errors i can see is in Compile Output:

    duplicate symbol _Target in:
    fresatura.o
    mainwindow.o
    duplicate symbol _Target in:
    fresatura.o
    moc_fresatura.o
    ld: 2 duplicate symbols for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    make: *** [CNCMaster.app/Contents/MacOS/CNCMaster] Error 1
    15:10:04: The process "/usr/bin/make" exited with code 2.
    Error while building/deploying project CNCMaster (kit: Desktop Qt 5.13.0 clang 64bit)
    When executing step "Make"
    15:10:04: Elapsed time: 00:03.

    i've searched in the project but i can't find duplicate



  • @thecipo76

    It may cause trouble, because you define two QObject - derived classes in one header file. Put your custom LineEdit in a separate headerfile (and .cpp) and include it in your dialog. Then try to compile it again :)



  • @pl45m4
    i've definded it in a separate file

    mylineedit.h

    #ifndef MYLINEEDIT_H
    #define MYLINEEDIT_H
    
    #include <QApplication>
    #include <QLineEdit>
    
    extern QString Target;
    
    class MyLineEdit : public QLineEdit
    {
        Q_OBJECT
    public:
        MyLineEdit(QWidget *parent = nullptr) : QLineEdit(parent){}
    protected:
        void focusOutEvent(QFocusEvent *event)
        {
           QLineEdit::focusOutEvent(event);
           QWidget * widgetName = qApp->focusWidget();
           Target = widgetName->objectName();
    
            if(!hasAcceptableInput())
            {
                setFocus();
            }
    
        }
    signals:
    };
    
    #endif // MYLINEEDIT_H
    
    

    and i've #included it in fresatura.cpp

    #include "mylineedit.h"
    

    but no way..

    Undefined symbols for architecture x86_64:
    "_Target", referenced from:
    MyLineEdit::focusOutEvent(QFocusEvent*) in moc_mylineedit.o
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    make: *** [CNCMaster.app/Contents/MacOS/CNCMaster] Error 1
    15:32:58: The process "/usr/bin/make" exited with code 2.
    Error while building/deploying project CNCMaster (kit: Desktop Qt 5.13.0 clang 64bit)
    When executing step "Make"
    15:32:58: Elapsed time: 00:02.


  • Lifetime Qt Champion

    @thecipo76 said in QLineEdit lostFocus problem:
    extern QString Target;

    and then in the mylineedit.CPP file you also have

    QString Target;

    so its actually defined ?



  • @mrjj ok i've defined it in .cpp file and works..
    but i've lost Target value


  • Lifetime Qt Champion

    Hi
    Can you explain the original issue ?
    If you click on lineEdit , then click on keyboard, then
    lineedit loose its focus ?



  • @mrjj No, if i click on "1" pushbutton i have to read Target in order to know in wich mylineedit i have to insert "1".

    Target is the mylineedit who lost focus

    i don't know if it's clear


  • Lifetime Qt Champion

    @thecipo76
    well first of all the buttons should have NoFocus set so clicking them do not steal focus.
    There is no reason for it to lose focus unless you pop something else up first that takes focus.
    But in your case, its not keyboard that steal it but something else
    that takes focus while in the window ??



  • @mrjj Ah.. with NoFocus setted i don't need to subclass QLineEdit
    and it's all more easy

    Thank you very much


  • Lifetime Qt Champion

    @thecipo76
    Yep it helps a lot. :)
    I used qApp->focusWidget(); and sendEvent (key down / key up ) to post the keys to any widget that has keyboard focus and it works pretty well.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.