New Qt user here (also not an avid C++ programmer, so excuse me if my terminology isn't spot on). I am learning how to develop my own digital instrument cluster. I have managed to create my own graphical objects (horizontal bar graph) using QQuickPaintedItem. I have also managed to connect said objects to my own custom designed ECU over a network.
I want to add an "onClicked" event to the horizontal bar graphs, so that a new window (QWidget?) is displayed when the user clicks/presses an object. This new window would show the configuration parameters for the respective device that the horizontal bar graph is tied to. My intent is to design a generic QML window specific to pressure, temperature, etc. devices. For example, pressing the "Oil Temp", "Intake Air Temp", or "Coolant Temp" objects would take you to the generic QML window for temperature devices, and the parameters for whatever device was pressed would be displayed.
A couple questions that I have are as follows:
How do I add an "onClicked" event to my horizontal bar graph? I am assuming that I need to use MouseEvents, however, exact implementation of mouse events in my case is escaping me. I am assuming that once a click event is registered, that I can just send a signal to open my new window. Examples would be extremely helpful.
Should I be using a QWidget to open the new window, or is there a better alternative? I want the new window to completely replace the main window. When the new window is open, I also do not want the main window sending/receiving network requests in the background. Any examples you could point me to?
horizontalbargraph.cpp
#include "horizontalBarGraph.h"
HorizontalBarGraph::HorizontalBarGraph(QQuickItem *parent)
:QQuickPaintedItem(parent),
_horizontalBarGraphWidth(266),
_minValue(0),
_maxValue(100),
_actualValue(50),
_sensorName("Sensor Name"),
_units("Units"),
_llEnabled(true),
_llValue(20),
_lEnabled(true),
_lValue(40),
_hhEnabled(true),
_hhValue(80),
_hEnabled(true),
_hValue(60)
{
}
void HorizontalBarGraph::paint(QPainter *painter)
{
QRectF rect = this->boundingRect();
painter->setRenderHint(QPainter::Antialiasing);
QPen pen = painter->pen();
pen.setCapStyle(Qt::FlatCap);
QFont bottomFont("Arial", 14, QFont::Bold);
QFont topFont("Arial", 16, QFont::Bold);
QColor yellow(245, 225, 27);
QColor red(226, 32, 40);
QColor blue(71, 92, 167);
QColor gray192(192, 192, 192);
QColor gray212(212, 212, 212);
QColor gray224(224, 224, 224);
//minValue, actualValue, maxValue
painter->save();
painter->setFont(bottomFont);
pen.setColor(gray224);
painter->setPen(pen);
painter->drawText(rect.adjusted(0, _horizontalBarGraphHeight - _yBarChart2, _widthValue - _horizontalBarGraphWidth, 0), Qt::AlignHCenter | Qt::AlignTop, QString::number((_minValue), 'f', 0)); //Draws minValue
painter->drawText(rect.adjusted(_horizontalBarGraphWidth - _widthValue, _horizontalBarGraphHeight - _yBarChart2, 0, 0), Qt::AlignHCenter | Qt::AlignTop, QString::number((_maxValue), 'f', 0)); //Draws maxValue
painter->drawText(rect.adjusted(0, _horizontalBarGraphHeight - _yBarChart2, 0, 0), Qt::AlignHCenter | Qt::AlignTop, QString::number((_actualValue), 'f', 1)); //Draws actualValue
painter->restore();
//Bar chart background
painter->save();
painter->fillRect(rect.adjusted(_xBarChart, _yBarChart1, -_xBarChart, -_yBarChart2), gray224);
painter->restore();
//Lo
painter->save();
if(_lEnabled)
{
_scaleOutput = scale(_lValue, _minValue, _maxValue, _xBarChart, _horizontalBarGraphWidth - _xBarChart);
if(_actualValue <= _lValue)
{
painter->fillRect(rect.adjusted(_xBarChart, _yBarChart1, _scaleOutput - _horizontalBarGraphWidth, -_yBarChart2), yellow);
} else
{
painter->fillRect(rect.adjusted(_xBarChart, _yBarChart1, _scaleOutput - _horizontalBarGraphWidth, -_yBarChart2), gray212);
}
}
painter->restore();
//LoLo
painter->save();
if(_llEnabled)
{
_scaleOutput = scale(_llValue, _minValue, _maxValue, _xBarChart, _horizontalBarGraphWidth - _xBarChart);
if(_actualValue <= _llValue)
{
painter->fillRect(rect.adjusted(_xBarChart, _yBarChart1, _scaleOutput - _horizontalBarGraphWidth, -_yBarChart2), red);
} else
{
painter->fillRect(rect.adjusted(_xBarChart, _yBarChart1, _scaleOutput - _horizontalBarGraphWidth, -_yBarChart2), gray192);
}
}
painter->restore();
//Hi
painter->save();
if(_hEnabled)
{
_scaleOutput = scale(_hValue, _minValue, _maxValue, _xBarChart, _horizontalBarGraphWidth - _xBarChart);
if(_actualValue >= _hValue)
{
painter->fillRect(rect.adjusted(_scaleOutput, _yBarChart1, -_xBarChart, -_yBarChart2), yellow);
} else
{
painter->fillRect(rect.adjusted(_scaleOutput, _yBarChart1, -_xBarChart, -_yBarChart2), gray212);}
}
painter->restore();
//HiHi
painter->save();
if(_hhEnabled)
{
_scaleOutput = scale(_hhValue, _minValue, _maxValue, _xBarChart, _horizontalBarGraphWidth - _xBarChart);
if(_actualValue >= _hhValue)
{
painter->fillRect(rect.adjusted(_scaleOutput, _yBarChart1, -_xBarChart, -_yBarChart2), red);
} else
{
painter->fillRect(rect.adjusted(_scaleOutput, _yBarChart1, -_xBarChart, -_yBarChart2), gray192);}
}
painter->restore();
//Sensor name, Units
painter->save();
painter->setFont(topFont);
pen.setColor(gray224);
painter->setPen(pen);
painter->drawText(rect.adjusted(_xBarChart, 0, 0, -_horizontalBarGraphHeight + _yBarChart1 - _heightBarChart / 2), Qt::AlignLeft | Qt::AlignBottom, _sensorName); //Draws sensor name
painter->drawText(rect.adjusted(0, 0, -_xBarChart, -_horizontalBarGraphHeight + _yBarChart1 - _heightBarChart / 2), Qt::AlignRight | Qt::AlignBottom, _units); //Draws units
painter->restore();
//Arrow
painter->save();
QPainterPath path;
_scaleOutput = scale(_actualValue, _minValue, _maxValue, _xBarChart, _horizontalBarGraphWidth - _xBarChart);
path.moveTo(_scaleOutput - _heightBarChart / 2, _yBarChart1 - _heightBarChart / 2);
path.lineTo(_scaleOutput + _heightBarChart / 2, _yBarChart1 - _heightBarChart / 2);
path.lineTo(_scaleOutput, _yBarChart1 + _heightBarChart / 2);
path.closeSubpath();
painter->fillPath(path, blue);
painter->restore();
//Bounding box
painter->save();
_drawBoundingBox = false;
if(_llEnabled && _actualValue <= _llValue)
{
_drawBoundingBox = true;
_boundingBoxColor = red;
} else if (_lEnabled && _actualValue <= _lValue)
{
_drawBoundingBox = true;
_boundingBoxColor = yellow;
} else if (_hhEnabled && _actualValue >= _hhValue)
{
_drawBoundingBox = true;
_boundingBoxColor = red;
} else if (_hEnabled && _actualValue >= _hValue)
{
_drawBoundingBox = true;
_boundingBoxColor = yellow;
}
if(_drawBoundingBox && _boundingBoxFlash)
{
pen.setColor(_boundingBoxColor);
pen.setWidthF(_boundingBoxStrokeWidth);
painter->setPen(pen);
painter->drawRect(rect.adjusted(0, 0, 0, 0));
}
painter->restore();
}
qreal HorizontalBarGraph::getHorizontalBarGraphWidth()
{
return _horizontalBarGraphWidth;
}
qreal HorizontalBarGraph::getHorizontalBarGraphHeight()
{
return _horizontalBarGraphHeight;
}
qreal HorizontalBarGraph::getMinValue()
{
return _minValue;
}
qreal HorizontalBarGraph::getMaxValue()
{
return _maxValue;
}
qreal HorizontalBarGraph::getActualValue()
{
return _actualValue;
}
QString HorizontalBarGraph::getSensorName()
{
return _sensorName;
}
QString HorizontalBarGraph::getUnits()
{
return _units;
}
bool HorizontalBarGraph::isLlEnabled()
{
return _llEnabled;
}
qreal HorizontalBarGraph::getLlValue()
{
return _llValue;
}
bool HorizontalBarGraph::isLEnabled()
{
return _lEnabled;
}
qreal HorizontalBarGraph::getLValue()
{
return _lValue;
}
bool HorizontalBarGraph::isHEnabled()
{
return _hEnabled;
}
qreal HorizontalBarGraph::getHValue()
{
return _hValue;
}
bool HorizontalBarGraph::isHhEnabled()
{
return _hhEnabled;
}
qreal HorizontalBarGraph::getHhValue()
{
return _hhValue;
}
bool HorizontalBarGraph::isBoundingBoxFlashing()
{
return _boundingBoxFlash;
}
void HorizontalBarGraph::setHorizontalBarGraphWidth(qreal width)
{
if(_horizontalBarGraphWidth == width)
return;
_horizontalBarGraphWidth = width;
update();
emit widthChanged();
}
void HorizontalBarGraph::setHorizontalBarGraphHeight(qreal height)
{
if(_horizontalBarGraphHeight == height)
return;
//This object was designed to have a constant height. This method is technically not needed,
//but qt appears to require it.
//_horizontalBarGraphHeight = height;
//update();
//emit heightChanged();
}
void HorizontalBarGraph::setMinValue(qreal minValue)
{
if(_minValue == minValue)
return;
_minValue = minValue;
update();
emit minValueChanged();
}
void HorizontalBarGraph::setMaxValue(qreal maxValue)
{
if(_maxValue == maxValue)
return;
_maxValue = maxValue;
update();
emit maxValueChanged();
}
void HorizontalBarGraph::setActualValue(qreal actualValue)
{
if(_actualValue == actualValue)
return;
_actualValue = actualValue;
update();
emit actualValueChanged();
}
void HorizontalBarGraph::setSensorName(QString sensorName)
{
if(_sensorName == sensorName)
return;
_sensorName = sensorName;
update();
emit sensorNameChanged();
}
void HorizontalBarGraph::setUnits(QString units)
{
if(_units == units)
return;
_units = units;
update();
emit unitsChanged();
}
void HorizontalBarGraph::enableLl(bool llEnabled)
{
if(_llEnabled == llEnabled)
return;
_llEnabled = llEnabled;
update();
emit enableLlChanged();
}
void HorizontalBarGraph::setLlValue(qreal llValue)
{
if(_llValue == llValue)
return;
_llValue = llValue;
update();
emit llValueChanged();
}
void HorizontalBarGraph::enableL(bool lEnabled)
{
if(_lEnabled == lEnabled)
return;
_lEnabled = lEnabled;
update();
emit enableLChanged();
}
void HorizontalBarGraph::setLValue(qreal lValue)
{
if(_lValue == lValue)
return;
_lValue = lValue;
update();
emit lValueChanged();
}
void HorizontalBarGraph::enableH(bool hEnabled)
{
if(_hEnabled == hEnabled)
return;
_hEnabled = hEnabled;
update();
emit enableHChanged();
}
void HorizontalBarGraph::setHValue(qreal hValue)
{
if(_hValue == hValue)
return;
_hValue = hValue;
update();
emit hValueChanged();
}
void HorizontalBarGraph::enableHh(bool hhEnabled)
{
if(_hhEnabled == hhEnabled)
return;
_hhEnabled = hhEnabled;
update();
emit enableHhChanged();
}
void HorizontalBarGraph::setHhValue(qreal hhValue)
{
if(_hhValue == hhValue)
return;
_hhValue = hhValue;
update();
emit hhValueChanged();
}
void HorizontalBarGraph::setBoundingBoxFlash(bool flash)
{
if(_boundingBoxFlash == flash)
return;
_boundingBoxFlash = flash;
update();
emit boundingBoxFlashChanged();
}
qreal HorizontalBarGraph::scale(qreal input, qreal inputMin, qreal inputMax, qreal outputMin, qreal outputMax)
{
qreal output = (outputMax - outputMin) * (input - inputMin) / (inputMax - inputMin) + outputMin;
if(output > outputMax)
output = outputMax;
if(output < outputMin)
output = outputMin;
return output;
}
horizontalbargraph.h
#ifndef HORIZONTALBARGRAPH_H
#define HORIZONTALBARGRAPH_H
#include <QObject>
#include <QQuickPaintedItem>
#include <QPainter>
class HorizontalBarGraph : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(qreal horizontalBarGraphWidth READ getHorizontalBarGraphWidth WRITE setHorizontalBarGraphWidth NOTIFY horizontalBarGraphWidthChanged)
Q_PROPERTY(qreal horizontalBarGraphHeight READ getHorizontalBarGraphHeight WRITE setHorizontalBarGraphHeight NOTIFY horizontalBarGraphHeightChanged)
Q_PROPERTY(qreal minValue READ getMinValue WRITE setMinValue NOTIFY minValueChanged)
Q_PROPERTY(qreal maxValue READ getMaxValue WRITE setMaxValue NOTIFY maxValueChanged)
Q_PROPERTY(qreal actualValue READ getActualValue WRITE setActualValue NOTIFY actualValueChanged)
Q_PROPERTY(QString sensorName READ getSensorName WRITE setSensorName NOTIFY sensorNameChanged)
Q_PROPERTY(QString units READ getUnits WRITE setUnits NOTIFY unitsChanged)
Q_PROPERTY(bool llEnable READ isLlEnabled WRITE enableLl NOTIFY enableLlChanged)
Q_PROPERTY(qreal llValue READ getLlValue WRITE setLlValue NOTIFY llValueChanged)
Q_PROPERTY(bool lEnable READ isLEnabled WRITE enableL NOTIFY enableLChanged)
Q_PROPERTY(qreal lValue READ getLValue WRITE setLValue NOTIFY lValueChanged)
Q_PROPERTY(bool hhEnable READ isHhEnabled WRITE enableHh NOTIFY enableHhChanged)
Q_PROPERTY(qreal hhValue READ getHhValue WRITE setHhValue NOTIFY hhValueChanged)
Q_PROPERTY(bool hEnable READ isHEnabled WRITE enableH NOTIFY enableHChanged)
Q_PROPERTY(qreal hValue READ getHValue WRITE setHValue NOTIFY hValueChanged)
Q_PROPERTY(bool boundingBoxFlash READ isBoundingBoxFlashing WRITE setBoundingBoxFlash NOTIFY boundingBoxFlashChanged)
public:
HorizontalBarGraph(QQuickItem *parent = nullptr);
virtual void paint(QPainter *painter);
qreal getHorizontalBarGraphWidth();
qreal getHorizontalBarGraphHeight();
qreal getMinValue();
qreal getMaxValue();
qreal getActualValue();
QString getSensorName();
QString getUnits();
bool isLlEnabled();
qreal getLlValue();
bool isLEnabled();
qreal getLValue();
bool isHhEnabled();
qreal getHhValue();
bool isHEnabled();
qreal getHValue();
bool isBoundingBoxFlashing();
void setHorizontalBarGraphWidth(qreal width);
void setHorizontalBarGraphHeight(qreal height);
void setMinValue(qreal minValue);
void setMaxValue(qreal maxValue);
void setActualValue(qreal actualValue);
void setSensorName(QString sensorName);
void setUnits(QString units);
void enableLl(bool llEnabled);
void setLlValue(qreal llValue);
void enableL(bool lEnabled);
void setLValue(qreal lValue);
void enableHh(bool hhEnabled);
void setHhValue(qreal hhValue);
void enableH(bool hEnabled);
void setHValue(qreal hValue);
void setBoundingBoxFlash(bool flash);
signals:
void horizontalBarGraphWidthChanged();
void horizontalBarGraphHeightChanged();
void minValueChanged();
void maxValueChanged();
void actualValueChanged();
void sensorNameChanged();
void unitsChanged();
void enableLlChanged();
void llValueChanged();
void enableLChanged();
void lValueChanged();
void enableHhChanged();
void hhValueChanged();
void enableHChanged();
void hValueChanged();
void boundingBoxFlashChanged();
private:
qreal _horizontalBarGraphWidth;
qreal _horizontalBarGraphHeight = 75;
qreal _minValue;
qreal _maxValue;
qreal _actualValue;
QString _sensorName;
QString _units;
bool _llEnabled;
qreal _llValue;
bool _lEnabled;
qreal _lValue;
bool _hhEnabled;
qreal _hhValue;
bool _hEnabled;
qreal _hValue;
qreal _xBarChart = 25;
qreal _yBarChart1 = 35;
qreal _yBarChart2 = 25;
qreal _heightBarChart = _horizontalBarGraphHeight - _yBarChart1 - _yBarChart2;
qreal _widthValue = _xBarChart * 2;
qreal _scaleOutput;
qreal _boundingBoxStrokeWidth = 7.5;
bool _drawBoundingBox;
QColor _boundingBoxColor;
bool _boundingBoxFlash;
qreal scale(qreal input, qreal inputMin, qreal inputMax, qreal outputMin, qreal outputMax);
};
#endif // HORIZONTALBARGRAPH_H
there is many virtual functions that you can rempliment for get mouse event and best function for mouse click is mouseRelease
if I understand correctly, you want to block all mouse signal in main window while the new windows is open. you can create a QDialog instead of using pure QWidget to ban all mouse interaction from main window .