Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

qt - How do I add click events to a QQuickItem?

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();

    e

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 .


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...