Как добавить события щелчка в QQuickItem?

Здесь новый пользователь Qt (также не заядлый программист на C++, так что извините, если моя терминология неверна). Я учусь разрабатывать свою собственную цифровую приборную панель. Мне удалось создать свои собственные графические объекты (горизонтальная гистограмма), используя QQuickPaintedItem. Мне также удалось подключить указанные объекты к моему собственному ECU по сети.

Я хочу добавить событие onClicked в горизонтальные гистограммы, чтобы новое окно (QWidget?) отображалось, когда пользователь щелкает/нажимает объект. В этом новом окне будут отображаться параметры конфигурации для соответствующего устройства, к которому привязана горизонтальная гистограмма. Я намерен разработать общее окно QML, специфичное для устройств давления, температуры и т. д. Например, нажатие объектов Oil Temp, Intake Air Temp или Coolant Temp приведет вас к общему окну QML для температурных устройств, и будут отображаться параметры для любого нажатого устройства.

Пара вопросов, которые у меня есть, заключаются в следующем:

  1. Как добавить событие onClicked в мою горизонтальную гистограмму? Я предполагаю, что мне нужно использовать MouseEvents, однако точная реализация событий мыши в моем случае ускользает от меня. Я предполагаю, что после регистрации события щелчка я могу просто отправить сигнал, чтобы открыть новое окно. Примеры были бы чрезвычайно полезны.

  2. Должен ли я использовать QWidget, чтобы открыть новое окно, или есть лучшая альтернатива? Я хочу, чтобы новое окно полностью заменило главное окно. Когда новое окно открыто, я также не хочу, чтобы главное окно отправляло/принимало сетевые запросы в фоновом режиме. Какие-нибудь примеры, на которые вы могли бы мне указать?

Комбинация приборов

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

person kubiej21    schedule 24.01.2021    source источник


Ответы (1)


существует множество виртуальных функций, которые вы можете заменить для получения события мыши, и лучшая функция для щелчка мыши — mouseRelease

если я правильно понимаю, вы хотите заблокировать все сигналы мыши в главном окне, пока открыты новые окна. вы можете создать QDialog вместо использования чистого QWidget, чтобы запретить любое взаимодействие с мышью в главном окне.

person SajadBlog    schedule 25.01.2021