SOLVED - QGraphicsObject zValue Apparently Ignored After Window Resized



  • I am currently working on a simple data plotting widget. For my x and y axes I'm displaying ranges of data currently displayed. So for the y axis with 100 items labeled item1 - item100, there are 2 QGraphicsObjects. The top object shows "item1" and "item50", the bottom shows "item51" and "item100". Here is a screen shot:

    !http://stalagmite.us/qtHelpImgs/yAxis.PNG(yAxis before hover)!

    As you can see, the top text is too long to fit in the axis. I would like to allow the user to hover the mouse over a range and have that range display on top of all other items in the plot. This functionality is working to some extent. Here is a screen shot:

    !http://stalagmite.us/qtHelpImgs/yAxis_hovered.PNG(yAxis during hover)!

    The problem is that if the main window is maximized then hovering does not bring the range object to the front. Resizing the window by dragging the edges sometimes results in the same.

    On hovering over range items on the y axis, I set the objects zValue to a high number. The code for this is in the paint method of graphicsVRangeItem.cpp.

    Relevant code is listed below. The code for SDVGraphicsAbstractRangeItem is not listed as it only has basic data which both SDVGraphicsHRangeItem and SDVGraphicsVRangeItem use.

    Any help would be appreciated.



  • graphicsAxisItem.cpp
    @
    SDVGraphicsAxisItem::SDVGraphicsAxisItem(QGraphicsItem* parent) : QGraphicsObject(parent)
    {
    sdvTableModel = NULL;
    width = height = 10;
    lowRange = highRange = NULL;
    axisMidIndex = 0;
    setAcceptHoverEvents(true);
    }

    SDVGraphicsAxisItem::~SDVGraphicsAxisItem()
    {
    }

    QRectF SDVGraphicsAxisItem::boundingRect() const
    {
    return QRectF(0, 0, width, height);
    }

    void SDVGraphicsAxisItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
    {
    QRectF rect = boundingRect();
    painter->fillRect(rect, Qt::white);
    }

    void SDVGraphicsAxisItem::setModel(const SDVTableModel* sdvTableModel)
    {
    this->sdvTableModel = sdvTableModel;
    QVector<QString> channelNames;
    QVector<QDateTime> timestamps;

    if (sdvTableModel) {
    if (axis == Y_Axis) {
    channelNames = sdvTableModel->getChannelNames();
    axisMidIndex = channelNames.size() * 0.5;

    if (!lowRange) {
    lowRange = new SDVGraphicsVRangeItem(this);
    lowRange->setMinIndex(0);
    lowRange->setMinText(channelNames[0]);
    lowRange->setMaxIndex(axisMidIndex);
    lowRange->setMaxText(channelNames[axisMidIndex]);
    }
    lowRange->setWidth(boundingRect().width());
    lowRange->setHeight(boundingRect().height() * 0.5);

    if (!highRange) {
    highRange = new SDVGraphicsVRangeItem(this);
    highRange->setMinIndex(axisMidIndex + 1);
    highRange->setMinText(channelNames[highRange->getMinIndex()]);
    highRange->setMaxIndex(channelNames.size() - 1);
    highRange->setMaxText(channelNames[highRange->getMaxIndex()]);
    }
    highRange->setWidth(boundingRect().width());
    highRange->setHeight(boundingRect().height() * 0.5);
    highRange->setY(boundingRect().height() * 0.5);
    } else if (axis == X_Axis) {
    timestamps = sdvTableModel->getTimestamps();
    axisMidIndex = timestamps.size() * 0.5;

    if (!lowRange) {
    lowRange = new SDVGraphicsHRangeItem(this);
    lowRange->setMinIndex(0);
    lowRange->setMinText(timestamps[0].toString("MM.dd.yy hh:mm:ss.z"));
    lowRange->setMaxIndex(axisMidIndex);
    lowRange->setMaxText(timestamps[axisMidIndex].toString("MM.dd.yy hh:mm:ss.z"));
    }
    lowRange->setWidth(boundingRect().width() * 0.5);
    lowRange->setHeight(boundingRect().height());

    if (!highRange) {
    highRange = new SDVGraphicsHRangeItem(this);
    highRange->setMinIndex(axisMidIndex + 1);
    highRange->setMinText(timestamps[highRange->getMinIndex()].toString("MM.dd.yy hh:mm:ss.z"));
    highRange->setMaxIndex(timestamps.size() - 1);
    highRange->setMaxText(timestamps[highRange->getMaxIndex()].toString("MM.dd.yy hh:mm:ss.z"));
    }
    highRange->setWidth(boundingRect().width() * 0.5);
    highRange->setHeight(boundingRect().height());
    highRange->setX(boundingRect().width() * 0.5);
    }
    }
    }

    void SDVGraphicsAxisItem::setAxis(AxisItemAxis axis)
    {
    this->axis = axis;
    }

    void SDVGraphicsAxisItem::setWidth(double width)
    {
    this->width = width;
    }

    void SDVGraphicsAxisItem::setHeight(double height)
    {
    this->height = height;
    }

    void SDVGraphicsAxisItem::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
    {
    QGraphicsObject::hoverEnterEvent(event);
    }
    @

    graphicsVRangeItem.h
    @
    class SDVGraphicsVRangeItem : public SDVGraphicsAbstractRangeItem
    {
    public:
    SDVGraphicsVRangeItem(QGraphicsItem* parent = 0);

    // Paints rectangle from boundingRect() with minText and maxText on the top and bottom respectively
    void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0);

    protected:
    virtual void hoverEnterEvent(QGraphicsSceneHoverEvent* event);
    virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent* event);

    private:
    QPixmap topLabel;
    QPixmap bottomLabel;
    QTextOption textOpt;
    QPainter topLblPainter;
    QPainter botLblPainter;
    bool hovered;
    int origZValue;
    };
    @

    graphicsVRangeItem.cpp
    @
    SDVGraphicsVRangeItem::SDVGraphicsVRangeItem(QGraphicsItem* parent) : SDVGraphicsAbstractRangeItem(parent)
    {
    setAcceptHoverEvents(true);
    hovered = false;
    setFlags(ItemIsMovable);
    origZValue = zValue();
    }

    void SDVGraphicsVRangeItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
    {
    QRectF rect = boundingRect();
    topLabel = QPixmap(rect.width(), rect.height() * 0.5);
    bottomLabel = QPixmap(rect.width(), rect.height() * 0.5);
    Qt::GlobalColor color = Qt::white;
    int hoveredWidth;

    if (hovered) {
    setZValue(std::numeric_limits<int>::max());
    hoveredWidth = qMax(painter->fontMetrics().boundingRect(getMinText()).width(), painter->fontMetrics().boundingRect(getMaxText()).width());
    rect.setWidth(hoveredWidth);
    topLabel = QPixmap(hoveredWidth, rect.height() * 0.5);
    bottomLabel = QPixmap(hoveredWidth, rect.height() * 0.5);
    } else {
    setZValue(origZValue);
    }

    topLblPainter.begin(&topLabel);
    botLblPainter.begin(&bottomLabel);
    topLblPainter.fillRect(topLabel.rect(), color);
    botLblPainter.fillRect(bottomLabel.rect(), color);
    topLblPainter.drawText(topLabel.rect(), getMinText());
    textOpt.setAlignment(Qt::AlignBottom);
    botLblPainter.drawText(bottomLabel.rect(), getMaxText(), textOpt);
    topLblPainter.end();
    botLblPainter.end();

    painter->drawPixmap(0,0, topLabel);
    painter->drawPixmap(0, topLabel.rect().height(), bottomLabel);
    painter->drawRect(rect);
    }

    void SDVGraphicsVRangeItem::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
    {
    hovered = true;
    QGraphicsObject::hoverEnterEvent(event);
    //update();
    }

    void SDVGraphicsVRangeItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* event)
    {
    //update();
    hovered = false;
    QGraphicsObject::hoverLeaveEvent(event);
    }
    @



  • I tried setting the zValue of the SDVGraphicsAxisItem to a high value and that appears to have fixed my problem.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.