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?