Smooth Zoom In QGraphicsView/ja: Difference between revisions
No edit summary |
No edit summary |
||
Line 1: | Line 1: | ||
[[Category:HowTo]]<br />[[Category:Learning::Demos_and_Examples]]<br />[[Category:snippets]]<br />[[Category:Japanese]] | |||
[[SmoothZoomInQGraphicsView|English]] '''日本語''' | [[SmoothZoomInQGraphicsView|English]] '''日本語''' | ||
=QGraphicsView でスムースなズーム機能の作り方= | = QGraphicsView でスムースなズーム機能の作り方 = | ||
QGraphicsView を使ったプログラムですばらしい機能とはもちろん(例えば、Google Earth のような)スムースなズーム機能です。その実装のためには、QGraphicsView を継承した独自ウィジェットを作成する必要があります。 | QGraphicsView を使ったプログラムですばらしい機能とはもちろん(例えば、Google Earth のような)スムースなズーム機能です。その実装のためには、QGraphicsView を継承した独自ウィジェットを作成する必要があります。 | ||
Line 9: | Line 11: | ||
もちろん、wheelEvent の再実装が必要です。まずはそのコードを示します。説明はその後に行います。 | もちろん、wheelEvent の再実装が必要です。まずはそのコードを示します。説明はその後に行います。 | ||
ホイールの移動の「勢い」を計算して、_numScheduledScalings に加えます。[[ | <code><br />void MyQGraphicsView::wheelEvent ( QWheelEvent * event )<br />{<br /> int numDegrees = event->delta() / 8;<br /> int numSteps = numDegrees / 15; // QWheelEvent のドキュメントを参照してください<br /> _numScheduledScalings ''= numSteps;<br /> if (_numScheduledScalings * numSteps < 0) // ホイールが逆方向に動いた場合には、それまでに予定していたスケーリングをリセットします<br /> _numScheduledScalings = numSteps; | ||
<br /> QTimeLine *anim = new QTimeLine(350, this);<br /> anim->setUpdateInterval(20); | |||
<br /> connect(anim, SIGNAL (valueChanged(qreal)), SLOT (scalingTime(qreal)));<br /> connect(anim, SIGNAL (finished()), SLOT (animFinished()));<br /> anim->start();<br />}<br /></code> | |||
<br />ホイールの移動の「勢い」を計算して、_numScheduledScalings に加えます。[[Doc:QTimeLine]] のオブジェクトを作成して、 350ms の寿命の間に 20ms 毎に scalingTime() 関数を呼び出します。 | |||
<br /><code><br />void MyQGraphicsView::scalingTime(qreal x)<br />{<br /> qreal factor = 1.0'' qreal(_numScheduledScalings) / 300.0;<br /> scale(factor, factor);<br />}<br /></code> | |||
倍率(factor)はシーンをどのくらいズームしたいかによって決まります。ほんの少しだけズームしたいときには、ホイールをとても繊細に動かさなくてはならないでしょう。_numScheduledScalings は小さくなり、 factor はほとんど 1 になるでしょう。その逆に、ホイールを勢いよく回転させた場合には、_numScheduledScalings は大きくなり、シーンのズームは速くなるでしょう。 | 倍率(factor)はシーンをどのくらいズームしたいかによって決まります。ほんの少しだけズームしたいときには、ホイールをとても繊細に動かさなくてはならないでしょう。_numScheduledScalings は小さくなり、 factor はほとんど 1 になるでしょう。その逆に、ホイールを勢いよく回転させた場合には、_numScheduledScalings は大きくなり、シーンのズームは速くなるでしょう。 | ||
もちろん、動的に作成した QTimeLine の処理も必要です。<br /> | もちろん、動的に作成した QTimeLine の処理も必要です。<br /><code><br />void MyQGraphicsView::animFinished()<br />{<br /> if (_numScheduledScalings > 0)<br /> _numScheduledScalings—;<br /> else<br /> _numScheduledScalings++;<br /> sender()->~QObject();<br />} | ||
Revision as of 10:14, 24 February 2015
English 日本語
QGraphicsView でスムースなズーム機能の作り方
QGraphicsView を使ったプログラムですばらしい機能とはもちろん(例えば、Google Earth のような)スムースなズーム機能です。その実装のためには、QGraphicsView を継承した独自ウィジェットを作成する必要があります。
その基本的な考えはユーザがマウスのホイールをひとつ「動かす」たびに、新たに「スケーリングアクション」を作成するというものです。スケーリングする合計数は _numScheduledScalings に格納します。
もちろん、wheelEvent の再実装が必要です。まずはそのコードを示します。説明はその後に行います。
<br />void MyQGraphicsView::wheelEvent ( QWheelEvent * event )<br />{<br /> int numDegrees = event->delta() / 8;<br /> int numSteps = numDegrees / 15; // QWheelEvent のドキュメントを参照してください<br /> _numScheduledScalings ''= numSteps;<br /> if (_numScheduledScalings * numSteps < 0) // ホイールが逆方向に動いた場合には、それまでに予定していたスケーリングをリセットします<br /> _numScheduledScalings = numSteps;
<br /> QTimeLine *anim = new QTimeLine(350, this);<br /> anim->setUpdateInterval(20);
<br /> connect(anim, SIGNAL (valueChanged(qreal)), SLOT (scalingTime(qreal)));<br /> connect(anim, SIGNAL (finished()), SLOT (animFinished()));<br /> anim->start();<br />}<br />
ホイールの移動の「勢い」を計算して、_numScheduledScalings に加えます。Doc:QTimeLine のオブジェクトを作成して、 350ms の寿命の間に 20ms 毎に scalingTime() 関数を呼び出します。
<br />void MyQGraphicsView::scalingTime(qreal x)<br />{<br /> qreal factor = 1.0'' qreal(_numScheduledScalings) / 300.0;<br /> scale(factor, factor);<br />}<br />
倍率(factor)はシーンをどのくらいズームしたいかによって決まります。ほんの少しだけズームしたいときには、ホイールをとても繊細に動かさなくてはならないでしょう。_numScheduledScalings は小さくなり、 factor はほとんど 1 になるでしょう。その逆に、ホイールを勢いよく回転させた場合には、_numScheduledScalings は大きくなり、シーンのズームは速くなるでしょう。
もちろん、動的に作成した QTimeLine の処理も必要です。
void MyQGraphicsView::animFinished()
{
if (_numScheduledScalings > 0)
_numScheduledScalings—;
else
_numScheduledScalings++;
sender()->~QObject();
}