Search code examples
c++qtbitcoin

Adding a form to pre existing Qt application


Please excuse the vague title. What I am actually attempting is to add another tab to a Cryptocurrency wallet based on Bitcoin code but I am a bit new to Qt and I have come across an error I can't fix.

I have created the form in Qt Designer and used uic to turn it into .h file and referenced that in the bitcoingui.cpp/.h and Project.pro files.

The generated .h can be found here: radio.h

bitcoingui.cpp here: bitcoingui.cpp

bitcoingui.h here: bitcoingui.h

The error in question is:

src/qt/bitcoingui.cpp: In constructor ‘BitcoinGUI::BitcoinGUI(QWidget*)’:
src/qt/bitcoingui.cpp:119: error: no matching function for call to ‘Ui_Radio::Ui_Radio(BitcoinGUI* const)’
src/qt/radio.h:15: note: candidates are: Ui_Radio::Ui_Radio()
src/qt/radio.h:15: note:                 Ui_Radio::Ui_Radio(const Ui_Radio&)

src/qt/bitcoingui.cpp:129: error: no matching function for call to ‘QStackedWidget::addWidget(Ui_Radio*&)’
/opt/local/Library/Frameworks/QtGui.framework/Versions/4/Headers/qstackedwidget.h:67: note: candidates are: int QStackedWidget::addWidget(QWidget*)

src/qt/bitcoingui.cpp: In member function ‘void BitcoinGUI::gotoRadioPage()’:
src/qt/bitcoingui.cpp:781: error: no matching function for call to ‘QStackedWidget::setCurrentWidget(Ui_Radio*&)’
/opt/local/Library/Frameworks/QtGui.framework/Versions/4/Headers/qstackedwidget.h:80: note: candidates are: void QStackedWidget::setCurrentWidget(QWidget*)
src/qt/bitcoingui.cpp:785: error: no matching function for call to ‘BitcoinGUI::connect(QAction*&, const char [13], Ui_Radio*&, const char [17])’
/opt/local/include/QtCore/qobject.h:215: note: candidates are: static bool QObject::connect(const QObject*, const char*, const QObject*, const char*, Qt::ConnectionType)
/opt/local/include/QtCore/qobject.h:229: note:                 static bool QObject::connect(const QObject*, const QMetaMethod&, const QObject*, const QMetaMethod&, Qt::ConnectionType)
/opt/local/include/QtCore/qobject.h:338: note:                 bool QObject::connect(const QObject*, const char*, const char*, Qt::ConnectionType) const
make: *** [build/bitcoingui.o] Error 1

Which tells me that there are issues with line 119, 129, 781 and 785 in my bitcoingui.cpp

The lines in question are:

radioPage = new Ui_Radio(this);
centralWidget->addWidget(radioPage);
centralWidget->setCurrentWidget(radioPage);
connect(exportAction, SIGNAL(triggered()), radioPage, SLOT(exportClicked()));

Any ideas?


Solution

  • What's wrong?

    A valid Widget in Qt contains two parts:

    • Logic (Radio.h): Header file that depicted the class.

    • UI (UI_Radio.h): Generated from .ui by UIC. Usually, Qt's UIC use prefix UI_ to denote the difference from another header file. This header file just define a class to conveniently manage UI components, it's not a widget itself, just a normal C++ class.

    In your case, I think your Radio class should be a QWidget. It means in Radio.h you will at least have an explicitly defined constructor which assigns the parent widget. Besides, in Radio.cpp you will call setupUi to link the class and the UI (from UI_Radio.h).

    So this is what you should do:

    enter image description here

    But this is what you have done ( You used the name Radio.h here, but it doesn't matter ):

    enter image description here

    So your problem is: You didn't even implement the Radio class, while you should've made it a valid widget.

    Take a look at your Radio.h file (normally named as UI_Radio.h), there is no any constructor defined explicitly. That's why you got this error:

    src/qt/bitcoingui.cpp: In constructor ‘BitcoinGUI::BitcoinGUI(QWidget*)’:
    src/qt/bitcoingui.cpp:119: error: no matching function for call to ‘Ui_Radio::Ui_Radio(BitcoinGUI* const)’
    

    The Qt Designer cannot build a whole widget for you. It just help you create the layout of the widget, and you still need to implement the logic part of the widget.

    I would suggest you take a look at overviewPage to see how a widget should be implemented before it can be added to the main window.


    Explanation of Errors

    Your lines in questions:

    Line 119

    radioPage = new Ui_Radio(this);
    

    this point to BitcoinGUI, which is a widget. You failed to instantiate your Radio class here.

    Line 129 & 781

    centralWidget->addWidget(radioPage);
    centralWidget->setCurrentWidget(radioPage);
    

    Your radioPage has already failed to instantiate. Besides, it's not even a valid widget at all. Hence these two setters failed, take it for granted.

    Line 785

    connect(exportAction, SIGNAL(triggered()), radioPage, SLOT(exportClicked()));
    

    connect function only works for QObject, which QWidget inherits from. There is no doubt your radioPage failed here again.