How do I add click events to a QQuickItem?

318 Views Asked by At

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:

  1. 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.

  2. 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?

Instrument cluster

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
1

There are 1 best solutions below

0
On

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 .