[Solved] Problem with the use of *ui



  • Hello,

    I'm programming in a special project. A file ui_mainform.h is created each time that the programm is launched, so that I can't insert static variables for the defined widgets and use them in other .cpp because they everytime disapear. I'm trying to use a signal/slot to insert a QString at the end of a defined QTextEdit (in ui_mainform.h). I think that the *ui doesn't work well because I had to define it in both mainform.h and errorMsg.h, manually.

    Would anyone see what mistake there are? Thank you in advance!

    ui_mainform.h:

    @class Ui_MainForm
    {
    public:
    QTextEdit *errorBrowser;

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

    mainform.h:

    @namespace Ui {
    class MainForm;
    }

    class MainForm : public QMainWindow,
    private Ui::MainForm // ui_mainform automatic created
    {
    Q_OBJECT

    public:
    explicit MainForm(QWidget *parent = 0);
    ~MainForm();
    private:
    Ui::MainForm *ui;
    };@

    mainform.cpp:

    @#include "mainform.h"

    // Constructor: Erstellt das Hauptfenster
    MainForm::MainForm(QWidget *parent)
    : QMainWindow(parent)
    {
    ui->setupUi(this);

    camXPos = "ERROR!";
    camXPos = "ERROR!";
    camZPos = "ERROR!";

    }

    MainForm::~MainForm()
    {
    delete ui;
    }@

    errorMsg.h:

    @class errorMsg : public QObject
    {
    Q_OBJECT

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

    private:
    

    Ui::MainForm *ui;
    };@

    errorMsg.cpp:

    @#include "errorMsg.h"

    errorMsg::errorMsg()
    {}
    errorMsg::~errorMsg()
    {}

    void errorMsg::writeErrorMsg(QString msg, int value)
    {
    QTextEdit *line = new QTextEdit("Hello");
    QColor colorLine;
    QFont bold;
    bold.setBold(true);
    value=1;

    if (value==1)
    {
    colorLine.setRgb(191,13,9);
    line->setTextColor(colorLine);
    line->setFont(bold);
    }
    else
    {
    colorLine.setRgb(241,19,51);
    line->setTextColor(colorLine);
    line->setFont(bold);
    }

    line->setReadOnly(true);
    connect(line,SIGNAL(textChanged()),ui->errorBrowser,SLOT(insertPlainText(QString)));

    delete line;
    }@

    The current errors are:
    @
    errorMsg.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall errorMsg::metaObject(void)const " (?metaObject@errorMsg@@UBEPBUQMetaObject@@XZ)

    errorMsg.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall errorMsg::qt_metacast(char const *)" (?qt_metacast@errorMsg@@UAEPAXPBD@Z)

    errorMsg.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall errorMsg::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@errorMsg@@UAEHW4Call@QMetaObject@@HPAPAX@Z)@



  • Hi, it seems your build process is a bit broken, the linking errors occur because the linker does not see the QObject inside the file moc_errorMsg.obj, perhaps because the file moc_errorMsg.cpp is not generated?


  • Moderators

    Ouch, there's nothing wrong with ui mechanism, you're just using it (very) wrong ;)

    You should never modify ui_mainform.h file. It's a intermediate file. Treat it like .obj, .a, .lib etc. You don't mess with them. If you want to change something in gui there's a myform.ui file. This is the Qt designer file. Open it in the designer and do your changes there.

    Second thing is don't include the genreated ui_myform.h anywhere but the form class it actually implements this widget (mainform.h/.cpp in your case). Just because you included ui_ in errorMsg.cpp it doesn't mean it will know anything about the MainForm class or any particular instances of it.

    Third thing is your writeErrorMsg() method is completely wrong. You create a widget (line), you do bunch of stuff with it and right away you delete it. So what's the point of creating it in the first place? Also connect is not like calling a function. It will be called for you whenever the sender emits a signal. In your case the connection is severed in the next line when you delete the recipient.

    I could give you the "fix" code in here but I'm afraid you'll do the same mistakes again. I think you should start from the very basics of Qt. Maybe go through some of the ui tutorials and examples in the package. Once you grasp what widgets, signals and slots are and how they work fixing this should be a breeze.



  • Thank you for your reply!

    Yeah I think that's the problem because at the beginning of the debug, there is the line:

    @errorMsg.h(12): Note: No relevant classes found. No output generated.@

    But why is it not found? The errorMsg.h is written in my .pro file. How could I correct this problem?



  • Thanks for your advises Chris. I thought that my connect could change the ui-mainform file, I didn't know that it wouldn't be possible. Moreover, I can't modify the .ui file in Qt Designer, because it is "onlyRead". So I don't see how the add some text in my QTextEdit if I can't access it..

    The delete was a mistake, I removed it. Should I save my connect method or use something else to change the QTextEdit?


  • Moderators

    read-only means that user can't enter text into it. It doesn't mean the programmer can't ;)
    To change it in the designer just edit the text property in the properties panel.

    To change it from code create a setter method. Something like this:
    @
    void MainForm::printSomething(QString s) {
    ui->errorBrowser->appendPlainText(s);
    }
    @
    And just call it from wherever you need. Don't include ui_ file in other files. Instead pass around the pointer to MainForm so you can call this method on it.

    Btw. The ui member in not initialized in your code. Did you remove the initialization from the MainForm constructor? It should be something like this:
    @
    MainForm::MainForm(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainForm)
    {
    //in your code this would crash because ui was not initialized
    //here it is
    ui->setupUi(this);
    ...
    @


Log in to reply
 

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