views:

122

answers:

0

Hello,

I am trying to use the QGraphicsview, but I have lot of trouble with it.

My goal is very simple (for the moment): I want to create a basic pianokeyboard component, where you can set the number of keys, and where the keys automatically stretch when you resize the keyboard.

I am a newbie in QT, so maybe I am wrong in the design that I used.

I have a PianoKeyboard class, inheriting from QGraphicsview, and having a QGraphicsScene in it.

class PianoKeyboard : public QGraphicsView
{
    Q_OBJECT

public:
    PianoKeyboard(QWidget *parent = 0, u32 iNbKeys = 80);

    void    SetNumberKeys(u32 iNbKeys);
    virtual void resizeEvent( QResizeEvent * );

private:
    u32                 m_iNbKeys;
    QGraphicsScene*     m_pScene;
};

and I have a PianoKey class inheriting from QGraphicsItem

class PianoKey : public QGraphicsItem
{
public:
    PianoKey(QGraphicsItem *parent = 0);

    // Overridden functions from QGraphicsItem
    virtual QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    void SetSize(f32 fWidth, f32 fHeight);

private:
    f32 m_fWidth;
    f32 m_fHeight;
};

so first qeustion, does this design seems fine to you?

And now about positioning, I don't understand how it works, and how I sould do.

These are my class implementations

PianoKey::PianoKey(QGraphicsItem *parent)
    : QGraphicsItem(parent)
{
}

void PianoKey::SetSize(f32 fWidth, f32 fHeight)
{
    m_fWidth = fWidth;
    m_fHeight = fHeight;
}

QRectF PianoKey::boundingRect() const
{
    qreal penWidth = 1;
    return QRectF(-m_fWidth/2.f, -m_fHeight/2.f, m_fWidth, m_fHeight);
}

void PianoKey::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
    painter->setBrush(Qt::blue);
    painter->drawRect(-m_fWidth/2.f, -m_fHeight/2.f, m_fWidth, m_fHeight);
}


PianoKeyboard::PianoKeyboard(QWidget *parent, u32 iNbKeys) :
    QGraphicsView(parent)
{
    m_pScene = new QGraphicsScene(0, 0, 1.0, 1.0, this);
    this->setScene(m_pScene);
    SetNumberKeys(10);
}

void PianoKeyboard::resizeEvent( QResizeEvent * pEvent)
{
    if (pEvent->oldSize().width() > 0 && pEvent->oldSize().height() > 0)
    {
        scale(pEvent->size().width()/(f32)pEvent->oldSize().width(), pEvent->size().height()/(f32)pEvent->oldSize().height());
    }else
    {
        scale(pEvent->size().width(), pEvent->size().height());
    }
}

void PianoKeyboard::SetNumberKeys(u32 iNbKeys)
{
    m_iNbKeys = iNbKeys;
    f32 fPianoKeyWidth = 1.f/m_iNbKeys;
    for (u32 i = 0 ; i < m_iNbKeys ; i++)
    {        
        PianoKey* pKey = new PianoKey();
        pKey->setPos(i*fPianoKeyWidth, 0.f);
        pKey->SetSize(fPianoKeyWidth, 1.f);

        m_pScene->addItem(pKey);
    }
}

With this code I don't have what I want, I only see vertical lines at correct positions, but no blue rectangle as it should be.

And when I resize my window, it's very slow, and most of the time it freezes... I think he doesn't like the scale in resize event.

So do you have an idea?