十時から八時まで
Qtのフローティングボールメニュー
目次
元のリンク: Qt のフローティング ボール メニュー
I. 概要
最近、かっこいいフローティングメニューを作りたいと思っています メニューの広がりや美しさを考えると、Qtのアニメーションシステムやステートマシンの内容を学ぼうと考えています QtCreatorのサンプルチュートリアルを開いて閲覧してみたところ、チュートリアルは 2D Painting
役に立ちます Animated Tiles
。下の図に示すように、これら 2 つのデモでは展開アニメーションの作成方法が説明されており、興味のある学生は直接参照することもできます。
これら 2 つのデモを使用して、独自のプログラムの作成を開始できます。
2.エフェクト表示
次の 2 つの図は、作成者が作成した 2 つの無効なフローティング メニューをレンダリングしたもので、図 1 のコードが CSDN にアップロードされており、クレジットなしでダウンロードできることを示しています。図 2 のコードは、当面オープン ソースではありません。困っている友達はさらに相談できる
基本的な円形メニュー機能、コードは CSDN にアップロードされました - Qt 無効な PC 側円形メニュー、フローティング ボール メニュー、拡張アニメーション
高度なフローティング ボール メニュー、セカンダリ メニューの開始をサポート
3. コードを実現する
実装ファイルは比較的シンプルです. ヘッダファイルと実装ファイルのみです. ここでは主にヘッダファイルを公開し, 次に実装アイデアを説明します. 具体的な実装の詳細はソースコードをダウンロードすることで知ることができます.
1. メニュー項目
PopRingItemは、外部のQActionをバインドすることで通常のメニューと同様の機能を実現できるメニュー拡張アイテムです。
class PopRingItem : public QLabel
{
Q_OBJECT
public:
PopRingItem(QWidget *parent = 0);
~PopRingItem();
void SetRadius(int radius);
int GetRadius() const;
void BindAction(QAction * action);
signals:
void MouseEvent(bool);
protected:
virtual void enterEvent(QEvent * event) override;
virtual void leaveEvent(QEvent * event) override;
virtual void paintEvent(QPaintEvent * event) override;
protected:
int m_iRadius = 50;
QAction * m_actAction = nullptr;
};
2. サスペンドボール
フローティング ボールはメニュー項目から継承されたメニュー項目であり、メニュー項目と同様の機能があります。
class QVariantAnimation;
class QPropertyAnimation;
class PopRingMenu : public PopRingItem
{
Q_OBJECT
public:
PopRingMenu(QWidget *parent = 0);
~PopRingMenu();
signals:
void DoubleClicked();
public:
void SetActions(const QVector<QAction *> & acts);
void SetIcons(const QVector<QString> & icons);
void SetAnimationEnabled(bool enabled);
bool IsAnimationEnabled() const;
void SetSlowlyFade(bool enabled);
bool IsSlowlyFade() const;
void SetDistanced(int distance);
int GetDistanced() const;
void SetStartAngle(int angle);
int GetStartAngle() const;
void SetStepAngle(int angle);
int GetStepAngle() const;
void SetNormalMenuSize(int size);
int GetNormalMenuSize() const;
void SetNormalItemSize(int size);
int GetNormalItemSize() const;
protected:
virtual void enterEvent(QEvent * event) override;
virtual void leaveEvent(QEvent * event) override;
virtual void mouseDoubleClickEvent(QMouseEvent * event) override;
virtual void timerEvent(QTimerEvent * event) override;
virtual bool event(QEvent * event) override;
private slots:
void OnMouseEvent(bool);
private:
void UpdateActions(int msecond);
void ExpandMenu();
void CollapseMenu();
void SlowlyFade();
void QuicklyLighter();
bool IsUnderMouse() const;
void TryCollapseMenu();
void KillHideTimer();
private:
int m_iDistance = 70;
int m_iStartAngle = 0;
int m_iStepAngle = 60;
int m_iMenuSize = 70;
int m_iItemSize = 60;
int m_iTimerID = -1;
QPropertyAnimation * m_pOpacityAnimation = nullptr;
QVariantAnimation * m_pItemAnimation = nullptr;
QVector<PopRingItem *> m_items;
};
3. 重要なポイント
アニメーション オブジェクトを初期化し、アニメーションの継続時間とアニメーションの開始値と終了値を指定します。
アニメーション固有の実装関数は UpdateAction ではなく、アニメーションの開始値と終了値における現在のアニメーションの進行状況の値の割合に従って、現在のアニメーションの瞬間におけるメニュー項目の位置とサイズを計算します。
m_pItemAnimation = new QVariantAnimation(this);
m_pItemAnimation->setEasingCurve(QEasingCurve::InCubic);
m_pItemAnimation->setStartValue(ShowMenuStartValue);
m_pItemAnimation->setEndValue(ShowMenuEndValue);
m_pItemAnimation->setDuration(ShowMenuDuration);
connect(m_pItemAnimation, &QVariantAnimation::valueChanged, this, [this](const QVariant & v){
UpdateActions(v.toInt());
});
マウスが浮遊ボールに入ると拡大アニメーションを実行します
void PopRingMenu::ExpandMenu()
{
if (m_pItemAnimation)
{
if (m_pItemAnimation->state() != QAbstractAnimation::Running
&& m_pItemAnimation->currentValue().toInt() != ShowMenuEndValue)
{
m_pItemAnimation->setDirection(QVariantAnimation::Forward);
m_pItemAnimation->start();
}
}
else
{
UpdateActions(ShowMenuEndValue);
}
KillHideTimer();
QuicklyLighter();
}
- マウスが浮遊ボールから離れると、展開アニメーションとは逆のリトラクト アニメーションが実行されます。
- アニメーションを撤回するときに詳細な点があります。つまり、メニュー項目上にマウスを置いた場合、アニメーションを撤回できません。
void PopRingMenu::CollapseMenu()
{
if (false == IsUnderMouse())
{
if (m_pItemAnimation)
{
m_pItemAnimation->setDirection(QVariantAnimation::Backward);
m_pItemAnimation->start();
}
else
{
UpdateActions(ShowMenuStartValue);
}
KillHideTimer();
SlowlyFade();
}
}
アニメーション実装の詳細を展開および折りたたむ、アニメーションに従ってフレーム数を指定する、メニュー項目を比例的に拡大縮小および移動する
void PopRingMenu::UpdateActions(int msecond)
{
int curDistance = msecond * m_iDistance / ShowMenuEndValue;
for (int i = 0; i < m_items.size(); ++i)
{
PopRingItem * item = m_items.at(i);
double radians = qDegreesToRadians(m_iStepAngle * i * 1.0 + m_iStartAngle);
int offx = curDistance * qCos(radians);
int offy = curDistance * qSin(radians);
item->move(pos() + QPoint(offx, offy));
int curSize = msecond * m_iItemSize / ShowMenuEndValue;
item->SetRadius(curSize);
item->setVisible(ShowMenuStartValue != msecond);
};
::SetWindowPos(HWND(winId()), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}
フローティング ボールが指定された時間アクティブにならない場合、ユーザーへの視覚的な影響を軽減するためにフェードアウトします。
void PopRingMenu::SetSlowlyFade(bool enabled)
{
if (enabled)
{
if (nullptr == m_pOpacityAnimation)
{
m_pOpacityAnimation = new QPropertyAnimation(this, "opacity");
m_pOpacityAnimation->setEasingCurve(QEasingCurve::OutCubic);
m_pOpacityAnimation->setStartValue(SlowlyStartValue);
m_pOpacityAnimation->setEndValue(SlowLyEndValue);
m_pOpacityAnimation->setDuration(SlowlyFadeDuration);
}
}
else
{
if (m_pOpacityAnimation)
{
delete m_pOpacityAnimation;
m_pOpacityAnimation = nullptr;
}
}
}
4. 関連記事
- Qt メニュー項目のカスタマイズ
- Qt の QAbstractItemView の右クリック メニュー
- Qt ポップアップメニューのシャドウ
- Qt のカスタム QLineEdit 右クリックメニュー
- Qtのストックコンポーネント - 自己選択ストック - リストはドラッグアンドドロップ可能で、右クリックメニューが一般的に使用されます
一見の価値のある優れた記事:
記事が良いと思われた場合は、ご褒美をあげてもいいかもしれませんが、書くのは簡単ではありません、サポートに感謝します。あなたのサポートが私の最大のモチベーションです、ありがとう!!!
非常に重要 -- 声明を転載
-
当サイトの記事は特別な指示はなく、すべてオリジナルであり著作権で保護されています。転載する場合はリンクを使用し、原文の出典を明記してください。同時に原作者を書きます:朝十夜八 または Twowords
-
転載する場合は原文のまま転載してください 転載する際に本記事を改変する場合は事前にご連絡ください 転載の際、転載者に利益をもたらすような改変を行うことを禁止します
カテゴリ: qt プロジェクトのケース 、 qt の古典的な記事 、 qt 学習のケース 、 カスタム コントロール