PDA

View Full Version : QDialog show method's wierd problem on signal slot mechanism.



umituzun84
24th March 2010, 21:41
Hi All,

I have derived MyDialog class from QDialog. In MyDialog class's constructor I have connected some widget's signal and slots after setup ui. That's all for now. I use MyDıalog class from my application by;

MyDialog *md = new MyDialog(this);
md->show();

When I call show method at first time my connected slot's running one by one although there isn't any signal emitted under my control which are related each connected slot. But after first show method calling this situation disappered. I mean I hide window and show again and this situation doesn't exist.
But if I show and hide method before the signal slot connection in my constructor method there is no automatic slot running in my other show method calling.

Why my slots running automaticaly after my first show method calling? Do you have any idea?

Thanks in advance.

JohannesMunk
24th March 2010, 22:42
Please post all your code, so that we don't have to guess blindfolded.

Joh

umituzun84
25th March 2010, 07:07
Hi Joh,

#include "settingwindow.h"
#include "qgraph.h"
#include <QtCore/QDebug>
#include <QtGui/QShowEvent>
#include <QtGui/QColorDialog>

SettingWindow::SettingWindow(QWidget *parent)
: QDialog(parent)
{
ui.setupUi(this);

ui.groupBoxCurveSettings->hide();
layout()->setSizeConstraint(QLayout::SetFixedSize);

// To solve auto slot calling
show();
hide();

connect(ui.radioButtonScrollAutomatic, SIGNAL(clicked(bool)), this, SLOT(setPlotScrollType(bool)));
connect(ui.radioButtonScrollManual, SIGNAL(clicked(bool)), this, SLOT(setPlotScrollType(bool)));

connect(ui.doubleSpinBoxYMinLeft, SIGNAL(valueChanged(double)), this, SLOT(setPlotAxisScaleYLeft(double)));
connect(ui.doubleSpinBoxYMaxLeft, SIGNAL(valueChanged(double)), this, SLOT(setPlotAxisScaleYLeft(double)));
connect(ui.doubleSpinBoxYStepLeft, SIGNAL(valueChanged(double)), this, SLOT(setPlotAxisScaleYLeft(double)));

connect(ui.doubleSpinBoxYMinRight, SIGNAL(valueChanged(double)), this, SLOT(setPlotAxisScaleYRight(double)));
connect(ui.doubleSpinBoxYMaxRight, SIGNAL(valueChanged(double)), this, SLOT(setPlotAxisScaleYRight(double)));
connect(ui.doubleSpinBoxYStepRight, SIGNAL(valueChanged(double)), this, SLOT(setPlotAxisScaleYRight(double)));

connect(ui.doubleSpinBoxXStart, SIGNAL(valueChanged(double)), this, SLOT(setPlotAxisScaleXBottom(double)));
connect(ui.doubleSpinBoxXRange, SIGNAL(valueChanged(double)), this, SLOT(setPlotAxisScaleXBottom(double)));
connect(ui.doubleSpinBoxXStep, SIGNAL(valueChanged(double)), this, SLOT(setPlotAxisScaleXBottom(double)));

connect(this, SIGNAL(panned(int, int)), parent, SLOT(setPanned(int, int)));
connect(this, SIGNAL(plotScrollTypeChanged(const ushort)), parent, SLOT(setPlotScrollType(const ushort)));
connect(this, SIGNAL(plotAxisScaleChanged(QwtPlot::Axis, double, double, double)),
parent, SLOT(setPlotAxisScale(QwtPlot::Axis, double, double, double)));

connect(ui.pushButtonDefaults, SIGNAL(clicked()), parent, SLOT(setPlotAxisScaleDefaults()));
connect(ui.pushButtonDefaults, SIGNAL(clicked()), this, SLOT(updateAxisValues()));
connect(ui.comboBoxCurveName, SIGNAL(currentIndexChanged(int)), this, SLOT(updateCurveSettings()));
connect(ui.pushButtonCurveSettings, SIGNAL(clicked()), this, SLOT(updateCurveSettings()));
connect(ui.pushButtonCurveColorButton, SIGNAL(clicked()), this, SLOT(setCurveColor()));
connect(ui.pushButtonCurveApply, SIGNAL(clicked()), this, SLOT(setCurveSettings()));
}

SettingWindow::~SettingWindow()
{
}

void SettingWindow::setPlotScrollType(const bool scrollType)
{
QRadioButton *radioButton = qobject_cast<QRadioButton*>(sender());

if(!radioButton)
{
return;
}

if(ui.radioButtonScrollAutomatic == radioButton)
{
emit plotScrollTypeChanged(0);
emit panned(0, 0);
}
else if(ui.radioButtonScrollManual == radioButton)
{
emit plotScrollTypeChanged(1);
emit panned(0, 0);
}
}

void SettingWindow::setPlotAxisScaleYLeft(const double)
{
double min = ui.doubleSpinBoxYMinLeft->value();
double max = ui.doubleSpinBoxYMaxLeft->value();
double step = ui.doubleSpinBoxYStepLeft->value();

emit plotAxisScaleChanged(QwtPlot::yLeft, min, max, step);
emit panned(0, 0);
}

void SettingWindow::setPlotAxisScaleYRight(const double)
{
double min = ui.doubleSpinBoxYMinRight->value();
double max = ui.doubleSpinBoxYMaxRight->value();
double step = ui.doubleSpinBoxYStepRight->value();

emit plotAxisScaleChanged(QwtPlot::yRight, min, max, step);
emit panned(0, 0);
}

void SettingWindow::setPlotAxisScaleXBottom(const double)
{
double min = ui.doubleSpinBoxXStart->value();
double max = min + ui.doubleSpinBoxXRange->value();
double step = ui.doubleSpinBoxXStep->value();

emit plotAxisScaleChanged(QwtPlot::xBottom, min, max, step);
emit panned(0, 0);
}

void SettingWindow::showEvent(QShowEvent *event)
{
updateAxisValues();
updateCurveValues();
updateCurveSettings();

QDialog::showEvent(event);
}

void SettingWindow::updateAxisValues()
{
QGraph *graph = (QGraph*)parent();

ui.doubleSpinBoxYMinLeft->setValue(graph->plotAxisMin(QwtPlot::yLeft));
ui.doubleSpinBoxYMaxLeft->setValue(graph->plotAxisMax(QwtPlot::yLeft));
ui.doubleSpinBoxYStepLeft->setValue(graph->plotAxisStep(QwtPlot::yLeft));

ui.doubleSpinBoxYMinRight->setValue(graph->plotAxisMin(QwtPlot::yRight));
ui.doubleSpinBoxYMaxRight->setValue(graph->plotAxisMax(QwtPlot::yRight));
ui.doubleSpinBoxYStepRight->setValue(graph->plotAxisStep(QwtPlot::yRight));

ui.doubleSpinBoxXStart->setValue(graph->plotAxisMin(QwtPlot::xBottom));
ui.doubleSpinBoxXRange->setValue(graph->plotAxisRange(QwtPlot::xBottom));
ui.doubleSpinBoxXStep->setValue(graph->plotAxisStep(QwtPlot::xBottom));
}

void SettingWindow::updateCurveValues()
{
QGraph *graph = (QGraph*)parent();

ui.comboBoxCurveName->clear();

QwtPlotItemList plotItemList = graph->itemList(QwtPlotItem::Rtti_PlotCurve);

for(QwtPlotItemIterator it = plotItemList.begin(); it != plotItemList.end(); it++)
{
QwtPlotCurve *curve = (QwtPlotCurve*)(*it);
ui.comboBoxCurveName->addItem(curve->title().text());
}
}

void SettingWindow::updateCurveSettings()
{
QString curveName = (QString)ui.comboBoxCurveName->currentText();

QGraph *graph = (QGraph*)parent();
QwtPlotItemList plotItemList = graph->itemList(QwtPlotItem::Rtti_PlotCurve);

for(QwtPlotItemIterator it = plotItemList.begin(); it != plotItemList.end(); it++)
{
QwtPlotCurve *curve = (QwtPlotCurve*)(*it);
if(curve->title().text() == curveName)
{
int curveStyle = (int)curve->pen().style();
int curveWidth = (int)curve->pen().width();
curveColor = (QColor)curve->pen().color();
int curveAxis = (int)curve->yAxis();

ui.comboBoxCurveStyle->setCurrentIndex(curveStyle);
ui.spinBoxCurveWidth->setValue(curveWidth);
ui.labelCurveColorLabel->setPalette(QPalette(curveColor));
ui.labelCurveColorLabel->setAutoFillBackground(true);
ui.comboBoxCurveAxis->setCurrentIndex(curveAxis);
break;
}
}
}

void SettingWindow::setCurveColor()
{
QColor color = QColorDialog::getColor(Qt::green, this);

if(color.isValid())
{
curveColor = color;
ui.labelCurveColorLabel->setText(color.name());
ui.labelCurveColorLabel->setPalette(QPalette(curveColor));
ui.labelCurveColorLabel->setAutoFillBackground(true);
}
}

void SettingWindow::setCurveSettings()
{
QString curveName = (QString)ui.comboBoxCurveName->currentText();
Qt::PenStyle curveStyle = (Qt::PenStyle)ui.comboBoxCurveStyle->currentIndex();
int curveWidth = (int)ui.spinBoxCurveWidth->value();
QwtPlot::Axis curveAxis = (QwtPlot::Axis)ui.comboBoxCurveAxis->currentIndex();

QGraph *graph = (QGraph*)parent();
QwtPlotItemList plotItemList = graph->itemList(QwtPlotItem::Rtti_PlotCurve);

for(QwtPlotItemIterator it = plotItemList.begin(); it != plotItemList.end(); it++)
{
QwtPlotCurve *curve = (QwtPlotCurve*)(*it);
if(curve->title().text() == curveName)
{
QPen curvePen = curve->pen();
curvePen.setStyle(curveStyle);
curvePen.setWidth(curveWidth);
curvePen.setColor(curveColor);
curve->setPen(curvePen);
curve->setYAxis(curveAxis);
break;
}
}
}

This is my own dialog which called SettingWindow. If I call show method at first time after initialized the SettingWindow it automatically enter my all connected slots, but after I call another show methods there is no implicitly calling. To solve this problem I have added show and hide methods before connections.

Thanks in advance.

JohannesMunk
25th March 2010, 10:54
Hi!

Please use the forums-code-tags! In the advanced edit there is a "#"-button!

I think that one of your slots is called on first show, because the value has changed between initialization and then.

Your code is not compilable as is.. so you will have to track down the source of the problem yourself. Remove the Show Hide Workaround. remove all connects - comment them out. And uncomment them one by one.

Maybe it has to do with values you set in Designer? A plain QDoubleSpinboxes ValueChanged doesn't fire on creation..



#include <QApplication>
#include <QDebug>
#include <QtGui>
#include <QtCore>

class MainForm : public QDialog
{ Q_OBJECT
public:
MainForm() {
spinbox = new QDoubleSpinBox(this);
connect(spinbox,SIGNAL(valueChanged(double)),this, SLOT(SpinBoxValueChanged(double)));
}
protected slots:
void SpinBoxValueChanged(double value) {
qDebug() << "Value changed";
}
private:
QDoubleSpinBox* spinbox;
};

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));

MainForm form;
form.setGeometry(100,100,800,600);
form.show();

return app.exec();
}

#include "main.moc"


Good luck!

Johannes

JohannesMunk
25th March 2010, 10:57
Aah..!! You do it yourself:



void SettingWindow::showEvent(QShowEvent *event)
{
updateAxisValues();
updateCurveValues();
updateCurveSettings();
QDialog::showEvent(event);
}


On first show.. this is called.. Thus updating all values.. Thus all ValueChanged-Slots are called..

If you want some other behaviour, you will have to change this :->

Johannes

umituzun84
25th March 2010, 12:14
Hi Johannes,

I have realized the explicit value change on controls in my update functions :D How dummy I am! Thanks so much for your helps. I solved this problem by kind of this codes;



ui.comboBoxCurveName->blockSignals(true); // For stop signal creation
ui.comboBoxCurveName->clear();

QwtPlotItemList plotItemList = graph->itemList(QwtPlotItem::Rtti_PlotCurve);

for(QwtPlotItemIterator it = plotItemList.begin(); it != plotItemList.end(); it++)
{
QwtPlotCurve *curve = (QwtPlotCurve*)(*it);
ui.comboBoxCurveName->addItem(curve->title().text());
}
ui.comboBoxCurveName->blockSignals(false); // For start signal creation

So there is no signal while I am manipulating controls attributes.

Thanks again.
Regards.