[Solved] Cannot transfert a public QWidget in another .cpp



  • Hello,

    I would like to use a QTextBrowser in another .cpp file and I have some problem to get it right. It's defined in my ui_mainform.h which is edited by Qt Designer. I would like to use it in errorMsg.cpp. Would anyone have an idea about this problem?

    In Ui_MainForm.h:

    @class Ui_MainForm
    {
    public:
    QTextBrowser *errorBrowser;

    void setupUi(QMainWindow *MainForm)
    {
    errorBrowser = new QTextBrowser(centralwidget);
    errorBrowser->setObjectName(QStringLiteral("errorBrowser"));
    errorBrowser->setGeometry(QRect(500, 490, 491, 141));
    }@

    In errorMsg.h:

    @#include "ui_mainform.h"
    class errorMsg : public QObject
    {
    Q_OBJECT

    public:
    errorMsg();
    ~errorMsg();
    void writeErrorMsg(QString msg, int value);
    };@

    In errorMsg.cpp:

    @#include "errorMsg.h"

    errorMsg::errorMsg() {}

    errorMsg::~errorMsg() {}

    void writeErrorMsg(QString msg, int value)
    {
    Ui_MainForm::errorBrowser->setText("Hello");
    Ui_MainForm::errorBrowser->show();
    }@



  • hi, do you want to just access the QTextBrowser from your errorMsg or also define it there (and not in the Ui_MainForm class)?
    @
    Ui_MainForm::errorBrowser
    @
    that doesn't work because the errorBrowser is not static!
    I think best practice would be if you have access to the object itself, but if you really need it like this you can just declare it static:
    @
    static QTextBrowser *errorBrowser;
    @
    remember in c++ you have to initialize static variables with nullptr or something, or you will get linker errors.



  • Thanks for your reply! I made it static and I made the initialization in the errorMsg.cpp:

    @Ui_MainForm::errorBrowser = nullptr;@

    But I gives the two errors

    @mainform.obj : error LNK2001: unresolved external symbol "public: static class QTextBrowser * Ui_MainForm::errorBrowser" (?errorBrowser@Ui_MainForm@@2PAVQTextBrowser@@A)

    errorMsg.obj : error LNK2001: unresolved external symbol "public: static class QTextBrowser * Ui_MainForm::errorBrowser" (?errorBrowser@Ui_MainForm@@2PAVQTextBrowser@@A)@

    I tried to make the initialization in the Ui_Mainform.h, but it didn't accept it..



  • you should do static initialization in Ui_MainForm.cpp usually, but it should also work in the header file (outside of the class obviously).

    example:
    @
    class Foo {
    private:
    static int x;
    };

    int Foo::x = 123;
    @
    maybe you put it in the wrong place?



  • I tried it in the header file, but it still doesn't work. I write the new code for Ui_Mainform.h here

    @class Ui_MainForm
    {
    public:
    static QTextEdit *errorBrowser;

    void setupUi(QMainWindow *MainForm)
    {
    errorBrowser = new QTextEdit(centralwidget);
    errorBrowser->setObjectName(QStringLiteral("errorBrowser"));
    errorBrowser->setGeometry(QRect(500, 490, 491, 141));
    }
    };
    QTextEdit errorBrowser = nullptr;@

    The nullptr seems not to work



    1. you need to write:
      @
      QTextEdit* Ui_MainForm::errorBrowser = nullptr;
      @
      or you will just declare a new global variable and not initialize the static one in your class! you also forgot the pointer, you need to use the exact same signature for the static initialization or it won't work. :)

    2. nullptr is a new keyword that comes with c++11, I don't know what c++ version you are using but you should consider using c++11 when possible. if not then use "NULL" instead of "nullptr".

    Tip: you can enable c++11 with this addition in the Qt .pro file (if your compiler supports it):
    @
    CONFIG += c++11
    @

    in your case "nullptr" didn't work because you forgot the pointer, and just used QTextEdit instead of QTextEdit* (yeah that is a major difference in c++).



  • I'm using Visual basic 2012, then c++11 I think.. I added your line in the Qt.pro for safety.

    I tried with @QTextEdit Ui_MainForm::errorBrowser = nullptr;@

    too, but an error comes on the word errorBrowser. It says:
    @"declaration is incompatible with TextEdit *Ui_MainForm::errorBrowser"@



  • hey sorry I updated my post above, you also missed the pointer there:
    @
    QTextEdit* Ui_MainForm::errorBrowser = nullptr; // see the * after QTextEdit
    @

    also visual studio 2012 does not support c++11, you need visual studio 2013 to use most features, but for "nullptr" it might be sufficient to use the 2012 version (I assume you mean visual studio and not visual basic haha).

    Edit: "Support For C++11 Features (Modern C++) in Visual Studio comparison chart":http://msdn.microsoft.com/en-us/library/hh567368.aspx



  • It seems to be almost ok now, but during the compiling, there are a lot a messages like that one:

    @mainform.obj : error LNK2005: "public: static class QTextEdit * Ui_MainForm::errorBrowser" (?errorBrowser@Ui_MainForm@@2PAVQTextEdit@@A) already defined in main.obj@



  • yeah that's why I said you should initialize it in the cpp file, if you include the .h file in multiple other files you can't do it like this! so move it to he cpp and it should be fine...



  • Ok, thanks for the advise. I did that and I have a new problem: how can I make my QTextEdit static with Qt Designer?

    If I make it static manual in Visual Studio it doesn't work because the program load everytime the .ui file from QtCreator and the static word is deleted.



  • I don't think you can do that with the designer, I didn't know that file was generated by the designer because you should not manually change generated files...
    then you need some other solution, if you don't want to put the static keyboard in there every time.

    Usually you would add a get method in your MainForm (either to the complete UI or just the QTextEdit you need. and then you can use the getter in your other class to access it, that should be better then static members anyway.



  • With the get method I have the same problem:

    • if I put the get function in ui_mainform.cpp, I have to declare it in .h, and this declaration goes away for each compiling
    • if I put the get function in the daughter class mainform.h, I don't have that problem, but the function get makes a error because the QTextEdit isn't a static variable


  • usually you should be able to access your ui from mainform.h, and never edit the ui_mainform.h yourself. that is hard to explain you may need a complete example to understand what I mean, but I don't have much time atm to write you a full example now.

    so quick example, you have the getter in your mainform.h
    @
    QTextEdit* getErrorBrowser() const { return ui->errorBrowser; }
    @
    I don't know why that does not work for you?



  • I write here my new program, maybe there is an error anywhere.. The command "ui->" doesn't work with we. I don't really know what it means.

    In mainform.h:

    @QTextEdit* getBrowser() const;@

    In mainform.cpp:

    @QTextEdit* MainForm::getBrowser() const
    {
    return Ui_MainForm::errorBrowser;
    }@

    In errorMsg.h:

    @#include "mainform.h"
    class errorMsg : public QObject
    {
    Q_OBJECT

    public:
    errorMsg();
    ~errorMsg();

    QTextEdit *browser;
    };@

    In errorMsg.cpp:

    @#include "errorMsg.h"

    errorMsg::errorMsg()
    {
    browser = MainForm::getBrowser();
    }

    errorMsg::~errorMsg()
    {
    }
    @



  • Ok I might need to explain, the "ui" pointer is the default pointer to your UI components, Qt Creator creates that pointer by default I don't know why you don't have any?? But that might be why it is so complicated for you :D

    I didn't use Qt widgets for some time, let me create a default project in Qt Creator.
    So I didn't write any code, just create a default widget application, now I have this in "mainwindow.h":
    @
    private:
    Ui::MainWindow *ui; // pointer to the UI
    @

    which gets initialized in the cpp file:
    @
    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);
    }
    @

    and you can use this "ui" pointer in the whole class to access UI elements, again I didn't write any code, this is created by Qt Creator for every UI form + class. so The question is why don't you have this or how did you create your application?



  • I think that it is the problem too. The whole program was written with Qt4 by another person and I had to adapt it for Qt5. Maybe it wasn't a widget project but an empty project.. I tried to create a new widget project and it gave the same lines.

    Is your MainWindow like my Ui_MainForm? Could I just copy these lines? And if yes where?



  • You can create an empty widget project and see for yourself maybe.
    MainWindow is the class you can modify and add stuff etc, the actual UI file is only available in the form of mainwindow.ui and the ui_mainwindow.h is created by qmake and the build process, so the ui_mainwindow.h is only a temporary file and not part of the project files in Qt creator, if you want you can take a look that file in the build folder, but you cannot edit it.

    As far as I know this was also the way of doing it with Qt 4, so this is not new with Qt 5 or anything! I don't know to be honest your project looks just messed up from what I can see, don't know how to help you like this sorry.


Log in to reply
 

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