No member named 'setMargin' in 'QwtPlotLayout' - Convert Qt4.7 to Qt5.8 - c++

I need to convert Qt legacy code from 4.7 to 5.8, I have a compilation error in Qt Creator 4.2.1 Clang 7.0(Apple) 64bit. I'm using latest Qwt 6.1.3
Looking in .cpp file
#include "frmMainChart_UI.h"
#include <QHeaderView>
#include <qwt_plot_layout.h>
#include <qwt_legend.h>
#include "mpiDateScale.h"
#include "mpiPercentScale.h"
void frmMainChart_UI::setupUI(QWidget *parent_)
{
frmMainTableViewTree_UI::setupUI(QMap<int, QString>(), false, parent_);
delete frmMainTableViewTree_UI::tableCopy;
delete frmMainTableViewTree_UI::table;
chart = new mpiChart(widget);
chart->setAxisScaleDraw(QwtPlot::xBottom, new mpiDateScale());
chart->setAxisScaleDraw(QwtPlot::yLeft, new mpiPercentScale());
chart->plotLayout()->setCanvasMargin(20);
chart->plotLayout()->setMargin(20); // BROKE convert Qt4 to Qt5
chartZoomer = new mpiPlotZoomer(chart->canvas()); // BROKE convert Qt4 to Qt5
chartLegend = new QwtLegend(chart);
chart->insertLegend(chartLegend, QwtPlot::RightLegend);
QLinearGradient grad(0, 0, 1, 1);
grad.setCoordinateMode(QGradient::StretchToDeviceMode);
grad.setColorAt(0, Qt::white);
grad.setColorAt(1, QColor(220, 220, 220));
2 Errors in .cpp
../src/ui/frmMainChart_UI.cpp:18:26: error: no member named 'setMargin' in 'QwtPlotLayout'
chart->plotLayout()->setMargin(20); // BROKE convert Qt4 to Qt5
../src/ui/frmMainChart_UI.cpp:19:23: error: no matching constructor for initialization of 'mpiPlotZoomer'
chartZoomer = new mpiPlotZoomer(chart->canvas()); // BROKE convert Qt4 to Qt5
^
5 warnings and 2 errors generated
make: *** [frmMainChart_UI.o] Error 1
06:58:25: The process "/usr/bin/make" exited with code 2.
Error while building/deploying project mypersonalindex (kit: Desktop Qt 5.8.0 clang 64bit)
When executing step "Make"
06:58:25: Elapsed time: 00:01.
The Qwt 6.1.3 Docs has member function http://qwt.sourceforge.net/class_qwt_plot_layout.html
void setCanvasMargin (int margin, int axis=-1)
But NO Member Function being used
setMargin
My C++ skill is pretty limited, do you see any minor tweaks that could convert this from Qt4 to Qt5. ... so what is the replacement?
Looking at mpiChart.h likely relates to canvas() error
#ifndef MPICHART_H
#define MPICHART_H
#include "qwt_plot.h"
class mpiChart : public QwtPlot
{
Q_OBJECT
public:
mpiChart(QWidget *parent_ = 0):
QwtPlot(parent_)
{}
public slots:
void exportChart();
};
#endif // MPICHART_H
And Looking in mpiPlotZoomer.h relates to canvas() error
#ifndef MPIPLOTZOOMER_H
#define MPIPLOTZOOMER_H
#include <qwt_plot_zoomer.h>
#include <qwt_plot_canvas.h> // JDL convert Qt4 to Qt5
#include <qwt_compat.h> // JDL convert Qt4 to Qt5
class mpiPlotZoomer: public QwtPlotZoomer
{
public:
mpiPlotZoomer(QwtPlotCanvas *canvas_):
QwtPlotZoomer(canvas_, false)
{
setTrackerMode(AlwaysOn);
}
virtual QwtText trackerText(const QwtDoublePoint &pos_) const;
};
#endif // MPIPLOTZOOMER_H

As the setMargin function has been removed between Qwt version you were using for Qt 4.7 and Qwt 1.6.3 you are using with 5.8, you have no other choice than:
Replace setMargin calls by setCanvasMargin if that fits your needs
Or, remove setMargin calls
Try both, and see which one looks the best when displaying the GUI.
For the canvas() error, it's hard to tell without seeing mpiChart and mpiPlotZoomer declaration. However, I'll give it a try:
canvas() used to return a QwtPlotCanvas* in the past. For recent versions of Qwt it returns a QWidget*. So if your mpiPlotZoomer constructor expects a QwtPlotCanvas* as parameter, you'll have to:
Replace mpiPlotZoomer parameters type from QwtPlotCanvas* by QWidget*. May work if the guy who wrote the mpiPlotZoomer class does not actually use and QwtPlotCanvas members/attributes (he may only use it for parenting purpose)
Or replace mpiPlotZoomer(chart->canvas()); by mpiPlotZoomer( qobject_cast<QwtPlotCanvas*>( chart->canvas() ) ); which will hoepfully work fine.

Related

How to build Qt-project in MSVC?

I'm trying build Qt project in MSVC 2019.
I installed Qt VS Tools v.2.10.1 (rev. 2), opened my Qt-project in MSVC through Qt VS Tools. But when I try to build it I keep getting the same error:
"E2422 defaulted default constructor cannot be constexpr because the corresponding implicitly declared default constructor would not be constexpr" in Qt-library file QtCore\qrunnable.h:
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QRUNNABLE_H
#define QRUNNABLE_H
#include <QtCore/qglobal.h>
#include <functional>
QT_BEGIN_NAMESPACE
class Q_CORE_EXPORT QRunnable
{
bool m_autoDelete = true;
Q_DISABLE_COPY(QRunnable)
public:
virtual void run() = 0;
constexpr QRunnable() noexcept = default; //<- error message points here
virtual ~QRunnable();
static QRunnable *create(std::function<void()> functionToRun);
bool autoDelete() const { return m_autoDelete; }
void setAutoDelete(bool autoDelete) { m_autoDelete = autoDelete; }
};
QT_END_NAMESPACE
#endif
In VC-project settings everything seems to be well (additional libraries and directories).
Can anyone tell me some hint how can I fix that?
Thanks a lot in advance!
I tried different Qt versions for MSVC 2019
:
5.15.2_msvc2019_64,
6.2.4_msvc2019_64,
6.3.2_msvc2019_64,
6.4.2_msvc2019_64,
but error is still here.

QT 5.15: Creating a QPushButton crashes a program

Using latest QT 5.15.0, c++20, cmake 3.17, MSVC 16.7.2
I have a simple QWidget: (all necessary includes defined in precompiled header)
widget.h
#pragma once
#ifndef _WIDGET_H_209323
#define _WIDGET_H_209323
class TestWidget: public QWidget {
Q_OBJECT
public:
explicit TestWidget(QWidget* parent = nullptr);
private:
QVBoxLayout* side_panel_;
private:
auto init_elements() -> void;
};
#endif
widget.cpp:
#include "widget.h"
TestWidget::TestWidget(QWidget* parent) : QWidget(parent) {
init_elements();
}
auto TestWidget::init_elements() -> void {
auto init_main_panel = [this]() {
side_panel_ = new QVBoxLayout();
QPushButton* main_view = new QPushButton("test");
side_panel_->addWidget(main_view);
};
init_main_panel();
this->setLayout(side_panel_);
}
The program compiles fine, but crashes at startup with Process finished with exit code -1073741511 (0xC0000139) and nothing else.
Changing QPushButton to any other widget, for example
QLabel* label = new QLabel(this);
label->setText("test");
side_panel_->addWidget(label);
works as expected, without any problems.
Actually just adding widget.h with QPushButton to CMakeLists.txt add_target, without including it in any other project files crashes the program at startup.
UPDATE:
Tried loading project into Visual Studio and got more meaningful error:
The procedure entry point
?hitButton#QPushButton##MEBA_NAEBVQPoint###Z
could not be located int the dynamic link library
UPDATE 2:
Changing QT version to 5.14.2 fixes this issue. Both versions installed as MSVC precompiled 64-bit (MSVC2017 for 5.14 and MSVC2019 for 5.15) from official QT installer.

Qt c2664 compiler error in ui setup

I am using Qt 5.7.1 (5.8) and when I try to compile my project, I get an error:
Error: C2664: "void Ui_OverviewHistogram::setupUi(QFrame *)" :
Converting from argument 1 of "OverviewHistogram *const " to "QFrame
*" not possible
(translated from german)
and I have no idea why... The strange thing is, that a lot of seamingly similar classes compile without any issue, just this one will not work. I tried to change the ui to a pointer, but it did not work.
The ui_overviewhistogram component of this class is a simple QFrame object designed completely in the Qt designer without any outside manual code 'hacking'.
I am relatively new to C++ and Qt and I can't figure out a solution (not even why this is a problem), can anyone help me with it?
My code:
overviewhistogram.h
#ifndef OVERVIEWHISTOGRAM_H
#define OVERVIEWHISTOGRAM_H
#include <QFrame>
#include <QColormap>
#include "AnalysisSession.h"
#include "ui_overviewhistogram.h"
namespace Ui {
class OverviewHistogram;
}
class OverviewHistogram : public QFrame
{
Q_OBJECT
public:
OverviewHistogram(Examination *examination, double max = 400, int w = 175, QWidget *parent = 0);
...
}
#endif // OVERVIEWHISTOGRAM_H
overviewhistogram.cpp
OverviewHistogram::OverviewHistogram(Examination *examination, double max, int w, QWidget *parent) :
QFrame(parent)
{
ui.setupUi(this);
...
}

qt4 designer add custom class

Hi i have made a gui in qt4 designer and want to add custom slots with custom class.
It project compiles nicely without errors but my custom function wont work what am i doing wrong? I will show u the header file qt4 designer made for me and ill show u my custom file as well as the main.cpp.. first the main.cpp
I have revised my code, here is what i have now i have added a file called sweetest.cpp and edited the sweetest.h here are my new file and the error i recieve..
First main.cpp
#include "ui_sweetguiform.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget *widget = new QWidget;
Ui::SweetGuiForm ui;
ui.setupUi(widget);
widget->show();
return app.exec();
}
now my custom header file sweetest.cpp
#include "sweetest.h"
// trying to include the .moc file wouldnt work at all.
now the sweettest.h file with my code
#include "ui_sweetguiform.h"
class SweetGuiForm : public QWidget
{
Q_OBJECT
public:
SweetGuiForm( ): ui( new Ui::SweetGuiForm )
{
ui->setupUi( this );
connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(on_buttonBox_accepted()));
}
public slots:
void on_buttonBox_accepted()
{
ui.textEdit->setText(QString::number(23));
}
protected:
Ui::SweetGuiForm* ui;
};
Here is the compile error i recieve.. I am really stuck
In file included from sweetest.cpp:1:
sweetest.h: In member function ‘void SweetGuiForm::on_buttonBox_accepted()’:
sweetest.h:16: error: request for member ‘textEdit’ in ‘((SweetGuiForm*)this)->SweetGuiForm::ui’, which is of non-class type ‘Ui::SweetGuiForm*’
make: *** [sweetest.o] Error 1
I think im getting closer
The way that signals and slots work is that you must connect a signal to a slot. In your code, the simplest way to do that is in the constructor for the SweetGuiForm. You need to add:
SweetGuiForm() : ui(new Ui::SweetGuiForm) {
ui->setupUi(this);
connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(on_buttonBox_accepted()));
}
When the buttonBox emits its accepted signal all slots connected to it will be called.
update 1
On further inspection of your code, you are also missing the Qt macros that are used by the Qt MOC (meta-object compiler) system (http://qt-project.org/doc/qt-4.8/moc.html):
class SweetGuiForm : public QWidget
{
Q_OBJECT
public:
...
};
You also have to push the code through the MOC tool. It will generate a source file that needs to be included in your source. As I recall, you must include that in a cpp file; inclusion in a header is problematic. The following should be sufficient:
sweetguiform.cpp:
#include "suiteguiform.h"
#include "sweetguiform.moc"
update 2
On further further reflection, I had forgotten about the automatic signal/slot connection feature when you name your slots using special names (such as on_buttonBox_accepted). There is a blog post on just that here: http://qtway.blogspot.com/2010/08/automatic-connections-using-qt-signals.html. I've not used it myself, so I can't comment on its ability to work when using a ui member variable, though I suspect that it does not work in that arrangement. Regardless, you still need the Q_OBJECT macro and MOC.
Ok guys i figured it out and thought ide share what i found.
First the documentation is excellent in qt4 use it.
I found you can use qt4 designer to generate the hearder files, first i complied it with out custom slots and generated the ui_sweetgui2.h, then i could open the sweetgui2.h file generated by the first compile i did delete what qt4 put in there and put my custom slots in at that stage. did my head in for hours.... days.
so here is the simplest app on earth but its got me started so here are the files and code that worked for me and the documentation basically got me to click on to whats going on.
main.cpp
Strait from the documentation just changed the class name "SweetGuiForm".
#include <QApplication>
#include "sweetgui2.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
SweetGuiForm sweetgui;
sweetgui.show();
return app.exec();
}
next sweetgui2.cpp
My first attempt at c++.. ugly but works. But again i found everything about getting the text from the textEdit and type casting it to a int in the calculator example and searching for toPlainText() in the qt4 assistant. notice below im including the file that i will define the new slots that ill show further on in my explanation. hope im making sense.
#include <QtGui>
#include "sweetgui2.h"
SweetGuiForm::SweetGuiForm(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
}
void SweetGuiForm::on_buttonBox_accepted()
{
QString stringamount = ui.textEdit->toPlainText();
int digitamount = stringamount.toInt();
ui.textEdit->setText(QString::number(25 + digitamount));
}
next sweetgui2.h the one we included above My custom header file with my custom slot.... simple as i said from the calculator example and twisted a lil.. you will get it this is not what it looks like when you generate it from designer on the first compile this is after i have deleted nearly all what was there and opened the calculator example and followed in the tutorial wich shows you how to make your first custom slot .
#ifndef SWEETGUI2_H
#define SWEETGUI2_H
#include "ui_sweetgui2.h"
class SweetGuiForm : public QWidget
{
Q_OBJECT
public:
SweetGuiForm(QWidget *parent = 0);
private slots:
void on_buttonBox_accepted();
private:
Ui::SweetGuiForm ui;
};
#endif // SWEETGUI2_H
Again Straight from the documentation. I used the calculator example to get the basic flow.
next ui_sweetgui2.h
I include this file because i was trying to add my slots to the sweetgui2.h that was generated by qt4 desinger. doesnt work guys ..so i compiled first with sweetgui2.h file you generate with the designer, i go to forms menu then view code that is where u can save header files. then of course save the ui file.
and compile then you end up with the ui_sweetgui2.h file wich looked like the sweetgui2.h generated by the designer
#ifndef UI_SWEETGUI2_H
#define UI_SWEETGUI2_H
#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QDialogButtonBox>
#include <QtGui/QHeaderView>
#include <QtGui/QTextEdit>
#include <QtGui/QWidget>
QT_BEGIN_NAMESPACE
class Ui_SweetGuiForm
{
public:
QDialogButtonBox *buttonBox;
QTextEdit *textEdit;
void setupUi(QWidget *SweetGuiForm)
{
if (SweetGuiForm->objectName().isEmpty())
SweetGuiForm->setObjectName(QString::fromUtf8("SweetGuiForm"));
SweetGuiForm->resize(486, 238);
buttonBox = new QDialogButtonBox(SweetGuiForm);
buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
buttonBox->setGeometry(QRect(150, 200, 181, 26));
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
textEdit = new QTextEdit(SweetGuiForm);
textEdit->setObjectName(QString::fromUtf8("textEdit"));
textEdit->setGeometry(QRect(150, 50, 221, 91));
retranslateUi(SweetGuiForm);
QObject::connect(buttonBox, SIGNAL(rejected()), SweetGuiForm, SLOT(close()));
QMetaObject::connectSlotsByName(SweetGuiForm);
} // setupUi
void retranslateUi(QWidget *SweetGuiForm)
{
SweetGuiForm->setWindowTitle(QApplication::translate("SweetGuiForm", "SweetGuiBack", 0, QApplication::UnicodeUTF8));
} // retranslateUi
};
namespace Ui {
class SweetGuiForm: public Ui_SweetGuiForm {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_SWEETGUI2_H
Then i recompiled again with my custom slots and shazam! now i can begin to learn some c++.
thanks for all the hints guys, between you all and the documentation i got there.
hope this helps. The main thing to look at is the order things are included i mean my sweetgui2.cpp file
includes the sweetgui2.h file. wich grabs all my custom stuff.
My sweetgui2.h file
includes the ui_sweetgui2.h wich has all the stuff the designer made when i did the first compile. Main.cpp calls my SweetGuiForm class .
As you all can see my first couple days with c++ but this is a good starting point. it made me put the basic flow together in my mind. qt4 assistant look at it.. its well explained and the examples seem very good. ho ho ho merry xmas. hope my explanation helps.

Qt: MainWindow->show() crashes program on call

I've been working on this program using Qt in c++ and so far so good. However I then needed to get this program moved to another machine. I have subversion, so I committed every file in the project folder and checked it out on the new machine. After jumping through some hoops to get it to successfully build and running, I get this error:
ASSERT: "dst.depth() == 32" in file qgl.cpp,.
invalid parameter passed to c runtime function qt
I tried stepping through the program to find the point where it crashes and found that it was after everything had been initialized and show() is called for the class that inherits the QMainWindow class. The c->showView() line calls QMianWindow->show().
----------main.cpp------------
#include <QApplication>
#include "ModelI.h"
#include "ControllerI.h"
#include "Model.h"
#include "Controller.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ModelI *m = new Model();
ControllerI *c = new Controller(m);
c->showView(); <- ERROR HERE
return a.exec();
}
The confusing part of the problem is that the program works perfectly fine on my machine when show() is called. I don't know what could be different between the two machines to make the program behave so differently. Both use the same version of Qt (SDK 2010.05). Both are developing with Eclipse. The only difference I can find is that my compiler is MinGW 4.5.0 and the other machine's is MinGW 4.5.2.
EDIT 1:
This is what Controller::showView() looks like.
void Controller::showView()
{
mView->show();
}
And this is how mView is initialized.
mView = new View(mModel, this);