0

这里是新的 Qt 用户(也不是狂热的 C++ 程序员,如果我的术语不准确,请见谅)。我正在学习如何开发自己的数字仪表盘。我已经设法使用 QQuickPaintedItem 创建了我自己的图形对象(水平条形图)。我还设法通过网络将这些对象连接到我自己定制设计的 ECU。

我想在水平条形图中添加一个“onClicked”事件,以便在用户单击/按下对象时显示一个新窗口(QWidget?)。这个新窗口将显示水平条形图所关联的各个设备的配置参数。我的意图是设计一个针对压力、温度等设备的通用 QML 窗口。例如,按下“Oil Temp”、“Intake Air Temp”或“Coolant Temp”对象将带您进入温度设备的通用 QML 窗口,并且将显示按下的任何设备的参数。

我有几个问题如下:

  1. 如何向水平条形图添加“onClicked”事件?我假设我需要使用MouseEvents,但是,在我的情况下,鼠标事件的确切实现正在逃避我。我假设一旦注册了点击事件,我就可以发送一个信号来打开我的新窗口。示例将非常有帮助。

  2. 我应该使用 QWidget 打开新窗口,还是有更好的选择?我希望新窗口完全取代主窗口。当新窗口打开时,我也不希望主窗口在后台发送/接收网络请求。你能指点我的任何例子吗?

仪表盘

水平条形图.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;
}

水平条形图.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
4

1 回答 1

0

有许多虚拟功能可以重新获得鼠标事件,鼠标点击的最佳功能是mouseRelease

如果我理解正确,您想在新窗口打开时阻止主窗口中的所有鼠标信号。您可以创建一个 QDialog 而不是使用纯 QWidget 来禁止来自主窗口的所有鼠标交互。

于 2021-01-25T05:09:32.103 回答