Qchart exception triggered - c++

I'm developing an application that shows 3 charts in the main window and everything works fine. but now I came across an error when I make the instance
of the main window inside the class of another window the application crush and when do the debugger shows an exception triggered in one of the charts.
I used a graphic view and promote to Qchartview and for each chart the code is this:
chart_1
QPieSlice *slice = pieSeries->slices().at(0);
QFont font = slice->labelFont() ;
font.setBold(true);
font.setPointSize(15);
slice->setExploded();
slice->setLabelVisible();
slice->setPen(QPen(Qt::darkGreen, 1));
slice->setBrush(Qt::darkBlue);
slice->setLabelFont(font);
QChart *chart = new QChart();
chart->addSeries(pieSeries);
chart->setTitle("<h2>Total money of each currency</h2>");
chart->setAnimationOptions(QChart::SeriesAnimations);
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignBottom);
pieSeries->setLabelsVisible();
pieSeries->setLabelsPosition(QPieSlice::LabelOutside);
for(auto slice : pieSeries->slices())
slice->setLabel(QString("%1%").arg(100*slice->percentage(), 0, 'f', 1));
ui->chartView_1->setChart(chart);
ui->chartView_1->setRenderHint(QPainter::Antialiasing);
chart_2
QChart *donutBreakdown = new QChart();
donutBreakdown->setAnimationOptions(QChart::AllAnimations);
donutBreakdown->setTitle("<h2>Cassettes Information</h2>");
donutBreakdown->legend()->setAlignment(Qt::AlignBottom);
donutBreakdown->addSeries(series1);
donutBreakdown->addSeries(pieSeriesPie2);
donutBreakdown->addSeries(series3);
pieSeriesPie2->setLabelsVisible();
pieSeriesPie2->setLabelsPosition(QPieSlice::LabelOutside);
double arm = 0.04;
for(int i = 0; i < pieSeriesPie2->count(); i++){
double arm = (double)i/24;
double arm2= i*0.040;
QPieSlice *slice1 = pieSeriesPie2->slices().at(i);
slice1->setLabelArmLengthFactor(arm2);
}
ui->chartView_2->setChart(donutBreakdown);
ui->chartView_2->setRenderHint(QPainter::Antialiasing);
the two charts are pie chart and the triggered exception is on chart_2
I already replaced the chart_2, already replaced the graphical view that I am using in form
the days that I am fighting this error.
please help me please

Your static_cast
m_slice = static_cast<CustomSlice *>(slice1);
is probably not working as intended. I guess you made the CustomSlice class yourself, which inherits QPieChart. Please take a look at the https://en.cppreference.com/w/cpp/language/static_cast.
Did you mean dynamic_cast? Comment the line(s) out and try to reproduce the error.

Related

Qt Charts Bar Plot Resize Crash

Situation:
I wrote a bar plot using QtCharts, QChartView, QChart, QBarSeries, QBarSet, QValueAxis and QCategoryAxis and it works fine.
Problem:
When i resize the window or use QRubberbandon the plot, it crashes.
What i tried:
Every other plot i wrote is not affected by that problem, including the ones using QStackedBarSeries. The Problem also occured in another program i wrote in the same situation.
Code - Head:
int D_Plot::Plot_Stat_Multi_MeanMedian(
QChartView *pChartView,
vector<vector<double> > *vv_SetSta,
bool pl_mean,
bool pl_sd,
bool pl_median,
bool pl_adm,
QString name_title,
QString name_categories,
QString name_y)
Code - Body:
//Chart
QChart *chart = new QChart();
chart->setTitle(name_title);
//Sets
QBarSet set_mean("Mean");
QBarSet set_sdev("Standard Deviation");
QBarSet set_medi("Median");
QBarSet set_aadm("Average Absolute Deviation from Median");
//Categories
QStringList categories;
//Series
QBarSeries *series = new QBarSeries();
for(unsigned int set = 0; set < vv_SetSta->size(); set++)
{
if(pl_mean) set_mean.append((*vv_SetSta)[set][c_STAT_MEAN_ARITMETIC]);
if(pl_sd) set_sdev.append((*vv_SetSta)[set][c_STAT_STAN_DEV_SAMPLE]);
if(pl_median) set_medi.append((*vv_SetSta)[set][c_STAT_MEDIAN]);
if(pl_adm) set_aadm.append((*vv_SetSta)[set][c_STAT_ABS_DEV_MED]);
categories.append(QString::number(set));
}
if(pl_mean) series->append(&set_mean);
if(pl_sd) series->append(&set_sdev);
if(pl_median) series->append(&set_medi);
if(pl_adm) series->append(&set_aadm);
chart->addSeries(series);
//Axis
QBarCategoryAxis *X_axis = new QBarCategoryAxis();
X_axis->append(categories);
X_axis->setTitleText(name_categories);
chart->setAxisX(X_axis, series);
QValueAxis *Y_axis = new QValueAxis();
Y_axis->setTitleText(name_y);
chart->setAxisY(Y_axis, series);
//Showing
pChartView->setChart(chart);
return ER_Okay;
You are creating your QBarSet objects locally (i.e. not via the new operator) and passing a pointer to these sets to the QBarSet::append method which AFAIK takes ownership if the objects pointed to i.e feels obliged to de-allocate them when going out of scope. This is bound to fail with locally allocated objects.

Qt programming QComboBox

I am using Qt and C++ to add some features to a freeware called: EASYPAINT.
I had to add a more intuitive method in which the users can see the actual width directly from the tool instead of changing numbers. ( just like in the new windows paint , where you can actually see the line thickness and not pixels.)
I am using a QComboBox. My question is (look at the code first), instead of having 20 (penSizeList->addItem), I know we can have addItems.... But what about the icon. for each Item, will I have to search for 20 different line thickness.png and add them? Or is there another method I can use?
And also, how can I get rid of the string in addItem, and only keep an image or icon in the QComboBox.
QComboBox *penSizeList = new QComboBox();
penSizeList->setIconSize(QSize(100,100));
penSizeList->setStatusTip("Pen Size");
QIcon ONEpxIcon(":/media/actions-icons/clear-gray.png");
QIcon THREEpxIcon(":/media/instruments-icons/canvas-lines1.png");
penSizeList->addItem(ONEpxIcon,"1px");
penSizeList->addItem(THREEpxIcon,"2px");
penSizeList->addItem(THREEpxIcon,"3px");
penSizeList->addItem(THREEpxIcon,"4px");
penSizeList->addItem(THREEpxIcon,"5px");
penSizeList->addItem(THREEpxIcon,"6px");
penSizeList->addItem(THREEpxIcon,"7px");
penSizeList->addItem(THREEpxIcon,"8px");
penSizeList->addItem(THREEpxIcon,"9px");
penSizeList->addItem(THREEpxIcon,"10px");
penSizeList->addItem(THREEpxIcon,"11px");
penSizeList->addItem(THREEpxIcon,"12px");
penSizeList->addItem(THREEpxIcon,"13px");
penSizeList->addItem(THREEpxIcon,"14px");
penSizeList->addItem(THREEpxIcon,"15px");
penSizeList->addItem(THREEpxIcon,"16px");
penSizeList->addItem(THREEpxIcon,"17px");
penSizeList->addItem(THREEpxIcon,"18px");
penSizeList->addItem(THREEpxIcon,"19px");
penSizeList->addItem(THREEpxIcon,"20px");
connect(penSizeList,SIGNAL(activated(int)), this, SLOT(penValueChanged(int)));
Try to do this in loop.
penSizeList->addItem(ONEpxIcon,"1px");
for(int i = 2; i < 21 ; i++)
{
penSizeList->addItem(THREEpxIcon,QString("%1px").arg(i));
}
Or if you have different icons for each line:
for(int i = 1; i < 21 ; i++)
{
penSizeList->addItem(QIcon(QString("iconLine%1.png").arg(i)),QString("%1px").arg(i));
}
If you want only icons, set empty string:
penSizeList->addItem(icon,"");
If you want full image then you should set this image as background. For example:
QPixmap pxmap("G:/2/qt.jpg");
QStandardItemModel *md = new QStandardItemModel;
QStandardItem *iii = new QStandardItem;
iii->setBackground(QBrush(Qt::red));
iii->setText("ss");
QStandardItem *iiii = new QStandardItem;
iiii->setBackground(QBrush(pxmap));
iiii->setText("ss");
md->setItem(1,0,iii);
md->setItem(0,0,iiii);
ui->comboBox->setModel(md);

Wrong background color in custom QWidget

In my GUI, I have a scrollable area and a widget to be displayed in it defined like so:
_scoreBoxScroll = new QScrollArea(this);
_scoreBoxScroll->setFrameShape(QFrame::NoFrame);
_scoreBoxWidget = new QWidget(this);
_scoreBoxWidgetLayout = new QHBoxLayout(_scoreBoxWidget);
Some custom widgets are added later in a function:
for (int i = 1; i <= _db->gamesPerRound(); ++i) {
GameWidget *newGame = new GameWidget(_scoreBoxWidget, i, _db->playersString(MT::singular), _db->boogerScore());
_scoreBoxWidgetLayout->addWidget(newGame);
}
_scoreBoxScroll->setWidget(_scoreBoxWidget);
This results in a wrong background color for the GameWidgets:
When I add those widgets in the constructor with the very same code (and the _db calls replaced with static values, as when the constructor is called, there's no _db yet), the widgets are displayed with the correct color:
In case this is interesting: the whole code can be found in git://l3u.de/muckturnier.git, the posted code resides in ScorePage/ScorePage.cpp.
Why is a different color displayed here? And how can I fix this? Thanks in advance for all help!
Edit: the code in the constructor used in the second example is (as I don't have _db there):
_scoreBoxWidget = new QWidget(this);
_scoreBoxWidgetLayout = new QHBoxLayout(_scoreBoxWidget);
_scoreBoxLayout->addWidget(_scoreBoxWidget);
for (int i = 1; i <= 2; ++i) {
GameWidget *newGame = new GameWidget(this, i, QString::fromUtf8("Paar"), 21);
_scoreBoxWidgetLayout->addWidget(newGame);
}
_scoreBoxScroll->setWidget(_scoreBoxWidget);
Edit: I have created a minimalistic demo in the "demo" branch on git://l3u.de:muckturnier.git – I would be very glad if anyone could explain this behaviour!
Okay, I can answer my question myself now. It's due to the fact that QScrollArea::setWidget() calls setAutoFillBackground(true) on the added widget. When I add a manual
_scoreBoxWidget->setAutoFillBackground(false);
after the
_scoreBoxScroll->setWidget(_scoreBoxWidget);
the background color is as expected.

Qt Scroll Area does not add in scroll bars

Hi guys I have to dynamically create push buttons depending on user inputs, therefore if user gives a large input number the widget containing the push buttons has to have the ability to scroll up and down. For this reason I am using QScrollArea. I generate the template in Qt designer and the UIC generates the code for me after which I add in my part which should handle dynamic creation of push buttons. However, I can not seem to get the vertical scroll bars to appear. Here is the relevant part of the code.
verticalWidget = new QWidget(FWHMWorkflowDialog);
verticalWidget->setObjectName(QString::fromUtf8("verticalWidget"));
verticalWidget->setMinimumSize(QSize(150, 0));
verticalWidget->setMaximumSize(QSize(150, 16777215));
verticalLayout_5 = new QVBoxLayout(verticalWidget);
verticalLayout_5->setObjectName(QString::fromUtf8("verticalLayout_5"));
scrollArea = new QScrollArea(verticalWidget);
scrollArea->setObjectName(QString::fromUtf8("scrollArea"));
scrollArea->setMaximumSize(QSize(150, 16777215));
scrollArea->setWidgetResizable(true);
scrollAreaWidgetContents = new QWidget();
scrollAreaWidgetContents->setObjectName(QString::fromUtf8("scrollAreaWidgetContents"));
scrollAreaWidgetContents->setGeometry(QRect(0, 0, 130, 432));
numberOfSlices = numberSlices;
for (int i = 0; i < numberOfSlices; i++)
{
QWidget *horizontalWidget = new QWidget(scrollAreaWidgetContents);
horizontalWidget->setMaximumSize(150,40);
horizontalWidget->setGeometry(QRect(0, i*40, 150, 40));
hWidgetList.push_back(horizontalWidget);
QHBoxLayout *hLayout = new QHBoxLayout(horizontalWidget);
hLayoutList.push_back(hLayout);
hLayout->setSizeConstraint(QLayout::SetMinimumSize);
hLayout->setContentsMargins(-1, 1, -1, 1);
QPushButton *pushButton = new QPushButton(horizontalWidget);
pushButtonList.push_back(pushButton);
QString temp = QString("m_sliceButton").arg(i);
pushButtonList[i]->setObjectName(temp);
pushButtonList[i]->setGeometry(QRect(10, 20+i*40, 98, 27));
hLayout->addWidget(pushButton);
QCheckBox *checkBox = new QCheckBox(horizontalWidget);
checkBoxList.push_back(checkBox);
temp = QString("m_checkBox").arg(i);
checkBoxList[i]->setObjectName(temp);
checkBoxList[i]->setEnabled(true);
checkBoxList[i]->setGeometry(QRect(110, 20+i*40, 21, 22));
hLayout->addWidget(checkBox);
}
scrollArea->setWidget(scrollAreaWidgetContents);
//scrollArea->setWidgetResizable(true);
verticalLayout_5->addWidget(scrollArea);
The output window always looks like the following.
In this example the input by the user is 25 however you can see that the 21st button is cut off and 4 other buttons are not visible.
The size window problem occurring after scroll functionality started working.
You need to add your horizontalWidget to a vertical widget like so:
QVBoxLayout* vLayout = new QVBoxLayout();
for (int i = 0; i < numberOfSlices; i++)
{
QWidget *horizontalWidget = new QWidget();
vLayout->addWidget(horizontalWidget);
....
}
scrollAreaWidgetContents->setLayout(vLayout);
You second problem looks like it comes from this line:
scrollArea = new QScrollArea(verticalWidget);
You're adding scrollArea directly to verticalWidget, but to get it to lay out the way you want you need to put it in a layout. Try the following instead:
QVBoxLayout* l = new QVBoxLayout();
l->addWidget(sliceLabel); // or whatever you call it
l->addWidget(scrollArea);
l->addWidget(clearButton); // again, your name here
verticalWidget->setLayout(l);
Try playing around with the QScrollBarPolicy.
http://doc.qt.digia.com/qt/qabstractscrollarea.html#horizontalScrollBarPolicy-prop
I'm guessing that the default behavior isn't working because there is something strange going on with layouts.

Segfault when adding Qwt plot to layout

I try to build chart demo using Qwt and C++. I've added the following code to button click handler:
QwtPlot *plot = new QwtPlot(QwtText("Demo"));
plot->setGeometry(0, 0, 100, 100);
QwtPlotCurve curve("Sine");
QVector<double> xs;
QVector<double> ys;
for (double x = 0; x < 100; x++)
{
xs.append(x);
ys.append(sin(x));
}
QwtPointArrayData *series = new QwtPointArrayData(xs, ys);
curve.setData(series);
curve.attach(plot);
plot->show();
QLayout *lay = ui->centralWidget->layout();
lay->addWidget(plot);
and it segfaults at addWidget(plot);.
What am I doing wrong?
The layout of centralWidget is probably NULL or you haven't initialized the ui (e.g. calling setUp()). Check the first case with if(lay == NULL) and the second by looking at your code.
If the first case is correct have a look at your UI file in QDesigner and add a layout.