Problem when create virtual class in Qt with Abstract Factory Design Pattern



  • I wanna create an application, so I learn Design Pattern and I use it for Qt programming. But, when I write code, I got many problem with it. Hope you help me... Thanks for advanced. Sorry for my English, I'm a non native speaker.

    Here is my code:

    widget.h
    @#ifndef WIDGET_H
    #define WIDGET_H

    #include <QtGui/QApplication>
    #include <QtGui/QLabel>
    #include <QtGui/QPushButton>
    #include <QtGui/QLineEdit>
    #include <QObject>

    class Widget
    {

    public:
    virtual void draw() = 0;
    };

    #endif // WIDGET_H
    @

    findwidget.h

    @#ifndef FINDWIDGET_H
    #define FINDWIDGET_H
    #include "widget.h"
    #include <QtGui/QWidget>
    #include <QtGui/QApplication>
    #include <QtGui/QHBoxLayout>
    #include <QtGui/QVBoxLayout>

    class FindWidget : public QWidget, public Widget
    {
    Q_OBJECT

    public:
    FindWidget(QWidget *parent = 0);
    void draw();
    protected:
    QLabel *label;
    QPushButton *pushButton;
    QPushButton *okFind;
    QLineEdit *lineEdit;
    };

    FindWidget::FindWidget(QWidget *parent)
    : QWidget(parent), Widget()
    {
    label = new QLabel("Find What");
    pushButton->setText("&Exit");
    okFind = new QPushButton("OK");
    lineEdit = new QLineEdit("");

    }

    void FindWidget::draw()
    {
    QHBoxLayout* hlayout = new QHBoxLayout();
    QHBoxLayout* hlayout1 = new QHBoxLayout();
    QVBoxLayout* vlayout = new QVBoxLayout();

    hlayout->addWidget(label);
    hlayout->addWidget(lineEdit);
    
    hlayout1->addWidget(okFind);
    hlayout1->addWidget(pushButton);
    
    vlayout->addLayout(hlayout);
    vlayout->addLayout(hlayout1);
    

    }

    #endif // FINDWIDGET_H
    @

    findandreplacewidget.h
    @
    #ifndef FINDANDREPLACEWIDGET_H
    #define FINDANDREPLACEWIDGET_H

    #include "widget.h"
    #include <QtGui/QApplication>
    #include <QtGui/QWidget>
    #include <QtGui/QHBoxLayout>
    #include <QtGui/QVBoxLayout>

    class Find_Replace : public QWidget, public Widget
    {
    Q_OBJECT
    protected:
    QLabel* rplBy;
    QLabel* label;

    QLineEdit* replaceBy;
    QLineEdit* lineEdit;
    
    QPushButton* okReplace;
    QPushButton* pushButton;
    

    public:
    Find_Replace(QWidget* parent = 0);
    void draw();

    };

    Find_Replace::Find_Replace(QWidget *parent)
    : QWidget(parent), Widget()
    {
    label = new QLabel("Find What");
    lineEdit = new QLineEdit("");
    pushButton = new QPushButton("&Exit");
    rplBy = new QLabel("Replace By");
    replaceBy = new QLineEdit("");
    okReplace = new QPushButton("OK");
    }

    void Find_Replace::draw()
    {
    QHBoxLayout* hlayout = new QHBoxLayout(this);
    QHBoxLayout* hlayout1 = new QHBoxLayout(this);
    QHBoxLayout* hlayout2 = new QHBoxLayout(this);
    QVBoxLayout* vlayout = new QVBoxLayout(this);

    hlayout->addWidget(label);
    hlayout->addWidget(lineEdit);
    
    hlayout1->addWidget(rplBy);
    hlayout1->addWidget(replaceBy);
    
    hlayout2->addWidget(okReplace);
    hlayout2->addWidget(pushButton);
    
    vlayout->addLayout(hlayout);
    vlayout->addLayout(hlayout1);
    vlayout->addLayout(hlayout2);
    
    setLayout(vlayout);
    

    }

    #endif // FINDANDREPLACEWIDGET_H
    @

    factory.h
    @
    #ifndef FACTORY_H
    #define FACTORY_H

    #include <QtGui/QApplication>
    #include "widget.h"
    #include "findwidget.h"
    #include "findandreplace.h"

    class Factory
    {
    public:
    virtual Widget* creatWidget() = 0;
    };

    class FactoryFind : public Factory
    {
    public:
    Widget* creatWidget()
    {
    return new FindWidget();
    }
    };

    class FactoryFind_Replace : public Factory
    {
    public:
    Widget* creatWidget()
    {
    return new Find_Replace();
    }
    };

    #endif // FACTORY_H

    @

    main.cpp

    @
    #include "factory.h"
    #include "widget.h"
    #include "findandreplace.h"
    #include "findwidget.h"

    int main (int argc, char* argv[])
    {
    QApplication app(argc, argv);

    Factory* factoryFind = new FactoryFind();
    Factory* factoryFind_Replace = new FactoryFind_Replace();
    
    Widget* findw;
    Widget* findrplc;
    
    findw = factoryFind->creatWidget();
    findw->draw();
    
    findrplc = factoryFind_Replace->creatWidget();
    findrplc->draw();
    
    
    return app.exec();
    

    }

    @

    And I have got many error like this:

    @moc_findwidget.o: In function FindWidget::draw()': moc_findwidget.cpp:(.text+0x30): multiple definition ofFindWidget::draw()'
    main.o:main.cpp:(.text+0x0): first defined here
    moc_findwidget.o: In function non-virtual thunk to FindWidget::draw()': moc_findwidget.cpp:(.text+0x180): multiple definition ofnon-virtual thunk to FindWidget::draw()'
    main.o:main.cpp:(.text+0x150): first defined here
    moc_findwidget.o: In function FindWidget::FindWidget(QWidget*)': moc_findwidget.cpp:(.text+0x190): multiple definition ofFindWidget::FindWidget(QWidget*)'
    main.o:main.cpp:(.text+0x380): first defined here
    moc_findwidget.o: In function FindWidget::FindWidget(QWidget*)': moc_findwidget.cpp:(.text+0x190): multiple definition ofFindWidget::FindWidget(QWidget*)'
    main.o:main.cpp:(.text+0x380): first defined here
    moc_findandreplace.o: In function Find_Replace::draw()': moc_findandreplace.cpp:(.text+0x30): multiple definition ofFind_Replace::draw()'
    main.o:main.cpp:(.text+0x160): first defined here
    moc_findandreplace.o: In function non-virtual thunk to Find_Replace::draw()': moc_findandreplace.cpp:(.text+0x240): multiple definition ofnon-virtual thunk to Find_Replace::draw()'
    main.o:main.cpp:(.text+0x370): first defined here
    moc_findandreplace.o: In function Find_Replace::Find_Replace(QWidget*)': moc_findandreplace.cpp:(.text+0x250): multiple definition ofFind_Replace::Find_Replace(QWidget*)'
    main.o:main.cpp:(.text+0x5e0): first defined here
    moc_findandreplace.o: In function Find_Replace::Find_Replace(QWidget*)': moc_findandreplace.cpp:(.text+0x250): multiple definition ofFind_Replace::Find_Replace(QWidget*)'
    main.o:main.cpp:(.text+0x5e0): first defined here
    collect2: error: ld returned 1 exit status
    make: *** [Abstract_Factory_Pattern] Error 1
    10:36:14: The process "/usr/bin/make" exited with code 2.
    Error while building/deploying project Abstract_Factory_Pattern (kit: Desktop)
    When executing step 'Make'@

    please help me!!!



  • Please help me !!!


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Please don't bump your own threads only within hours after posting it. Not everybody here lives in the same timezone as you or has an answer to your question.

    Since you are trying to learn Qt, I would advise you to go through the examples and demos given with Qt's packages. That will make things easier for you to learn the ropes.



  • Oke,
    Don't you have cpp files to hold the definitions? I see in your header files the class declaration and the function definitions. ?? Or are these just code snippets from your cpp file. Just to state the officious, but learn C++ (there are some great books out there that use Qt to do so: Introduction to C++ using Qt4) or post in a more readable way. Now there is no way we could possibly help you.



  • First of I would suggest that you add the "virtual" keyword infront of the method definitions of your classes that derive from the Widget class as I assume they are meant to implement the method of the abstract base class.

    e.g.:
    @
    class FindWidget : public QWidget, public Widget
    {
    Q_OBJECT

    public:
    FindWidget(QWidget *parent = 0);
    virtual void draw(); // <----- change is here
    protected:
    QLabel *label;
    QPushButton *pushButton;
    QPushButton *okFind;
    QLineEdit *lineEdit;
    };
    @



  • [quote author="SGaist" date="1373877054"]Hi and welcome to devnet,

    Please don't bump your own threads only within hours after posting it. Not everybody here lives in the same timezone as you or has an answer to your question.

    Since you are trying to learn Qt, I would advise you to go through the examples and demos given with Qt's packages. That will make things easier for you to learn the ropes.[/quote]

    Thanks for your reply. :)

    [quote author="Jeroentje@home" date="1373878476"]Oke,
    Don't you have cpp files to hold the definitions? I see in your header files the class declaration and the function definitions. ?? Or are these just code snippets from your cpp file. Just to state the officious, but learn C++ (there are some great books out there that use Qt to do so: Introduction to C++ using Qt4) or post in a more readable way. Now there is no way we could possibly help you. [/quote]

    Thanks for your reply. :)

    [quote author="KA51O" date="1373879552"]First of I would suggest that you add the "virtual" keyword infront of the method definitions of your classes that derive from the Widget class as I assume they are meant to implement the method of the abstract base class.

    e.g.:
    @
    class FindWidget : public QWidget, public Widget
    {
    Q_OBJECT

    public:
    FindWidget(QWidget *parent = 0);
    virtual void draw(); // <----- change is here
    protected:
    QLabel *label;
    QPushButton *pushButton;
    QPushButton *okFind;
    QLineEdit *lineEdit;
    };
    @ [/quote]

    Thanks for your reply. I got it, Let's my try again.


  • Moderators

    [quote author="paulwarburg" date="1373860332"]
    findwidget.h

    @#ifndef FINDWIDGET_H
    #define FINDWIDGET_H
    #include "widget.h"
    #include <QtGui/QWidget>
    #include <QtGui/QApplication>
    #include <QtGui/QHBoxLayout>
    #include <QtGui/QVBoxLayout>

    class FindWidget : public QWidget, public Widget
    {
    Q_OBJECT

    public:
    FindWidget(QWidget *parent = 0);
    void draw();
    protected:
    QLabel *label;
    QPushButton *pushButton;
    QPushButton *okFind;
    QLineEdit *lineEdit;
    };

    FindWidget::FindWidget(QWidget *parent)
    : QWidget(parent), Widget()
    {
    label = new QLabel("Find What");
    pushButton->setText("&Exit");
    okFind = new QPushButton("OK");
    lineEdit = new QLineEdit("");

    }

    void FindWidget::draw()
    {
    QHBoxLayout* hlayout = new QHBoxLayout();
    QHBoxLayout* hlayout1 = new QHBoxLayout();
    QVBoxLayout* vlayout = new QVBoxLayout();

    hlayout->addWidget(label);
    hlayout->addWidget(lineEdit);
    
    hlayout1->addWidget(okFind);
    hlayout1->addWidget(pushButton);
    
    vlayout->addLayout(hlayout);
    vlayout->addLayout(hlayout1);
    

    }

    #endif // FINDWIDGET_H
    @

    findandreplacewidget.h
    @
    #ifndef FINDANDREPLACEWIDGET_H
    #define FINDANDREPLACEWIDGET_H

    #include "widget.h"
    #include <QtGui/QApplication>
    #include <QtGui/QWidget>
    #include <QtGui/QHBoxLayout>
    #include <QtGui/QVBoxLayout>

    class Find_Replace : public QWidget, public Widget
    {
    Q_OBJECT
    protected:
    QLabel* rplBy;
    QLabel* label;

    QLineEdit* replaceBy;
    QLineEdit* lineEdit;
    
    QPushButton* okReplace;
    QPushButton* pushButton;
    

    public:
    Find_Replace(QWidget* parent = 0);
    void draw();

    };

    Find_Replace::Find_Replace(QWidget *parent)
    : QWidget(parent), Widget()
    {
    label = new QLabel("Find What");
    lineEdit = new QLineEdit("");
    pushButton = new QPushButton("&Exit");
    rplBy = new QLabel("Replace By");
    replaceBy = new QLineEdit("");
    okReplace = new QPushButton("OK");
    }

    void Find_Replace::draw()
    {
    QHBoxLayout* hlayout = new QHBoxLayout(this);
    QHBoxLayout* hlayout1 = new QHBoxLayout(this);
    QHBoxLayout* hlayout2 = new QHBoxLayout(this);
    QVBoxLayout* vlayout = new QVBoxLayout(this);

    hlayout->addWidget(label);
    hlayout->addWidget(lineEdit);
    
    hlayout1->addWidget(rplBy);
    hlayout1->addWidget(replaceBy);
    
    hlayout2->addWidget(okReplace);
    hlayout2->addWidget(pushButton);
    
    vlayout->addLayout(hlayout);
    vlayout->addLayout(hlayout1);
    vlayout->addLayout(hlayout2);
    
    setLayout(vlayout);
    

    }

    #endif // FINDANDREPLACEWIDGET_H
    @
    [/quote]

    if you have to place the implemenation in the header you need to use inline, like:
    @
    inline void FindWidget::draw()
    {
    QHBoxLayout* hlayout = new QHBoxLayout();
    QHBoxLayout* hlayout1 = new QHBoxLayout();
    QVBoxLayout* vlayout = new QVBoxLayout();

    hlayout->addWidget(label);
    hlayout->addWidget(lineEdit);
    
    hlayout1->addWidget(okFind);
    hlayout1->addWidget(pushButton);
    
    vlayout->addLayout(hlayout);
    vlayout->addLayout(hlayout1);
    

    }
    @
    That will help as well a bit.



  • Thanks for your help. I got it.
    I have one question for you.
    I wanna learn how to use Design Pattern for Qt programming. where I can find document?



  • It's a book, you're able to buy it in the Amazon store etc.
    Let me check out the link:
    "Qt Books":https://qt-project.org/books
    Here is a good reference list of books. Got myself the "Introduction to design patterns in C++ with Qt" and "Advanced Qt Programming: Creating Great Software with C++ and Qt 4". Still going through the second one, but the first one is very clear in C++ programming abilities.



  • Thanks for your link of books. It's greate!!!
    [quote author="Jeroentje@home" date="1373900122"]It's a book, you're able to buy it in the Amazon store etc.
    Let me check out the link:
    "Qt Books":https://qt-project.org/books
    Here is a good reference list of books. Got myself the "Introduction to design patterns in C++ with Qt" and "Advanced Qt Programming: Creating Great Software with C++ and Qt 4". Still going through the second one, but the first one is very clear in C++ programming abilities.[/quote]


Log in to reply
 

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