Qtのフローティングボールメニュー

十時から八時まで

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();
}
  1. マウスが浮遊ボールから離れると、展開アニメーションとは逆のリトラクト アニメーションが実行されます。
  2. アニメーションを撤回するときに詳細な点があります。つまり、メニュー項目上にマウスを置いた場合、アニメーションを撤回できません。
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. 関連記事

  1. Qt メニュー項目のカスタマイズ
  2. Qt の QAbstractItemView の右クリック メニュー
  3. Qt ポップアップメニューのシャドウ
  4. Qt のカスタム QLineEdit 右クリックメニュー
  5. Qtのストックコンポーネント - 自己選択ストック - リストはドラッグアンドドロップ可能で、右クリックメニューが一般的に使用されます

一見の価値のある優れた記事:

  1. Financial AP通信 - 製品
  2. グロドン製品
  3. Qtカスタムコントロールリスト
  4. 素晴らしい Qt ライブラリ

記事が良いと思われた場合は、ご褒美をあげてもいいかもしれませんが、書くのは簡単ではありません、サポートに感謝します。あなたのサポートが私の最大のモチベーションです、ありがとう!
 


非常に重要 -- 声明を転載

  1. 当サイトの記事は特別な指示はなく、すべてオリジナルであり著作権で保護されています。転載する場合はリンクを使用し、原文の出典を明記してください。同時に原作者を書きます:朝十夜八 または Twowords

  2. 転載する場合は原文のまま転載してください 転載する際に本記事を改変する場合は事前にご連絡ください 転載の際、転載者に利益をもたらすような改変を行うことを禁止します


闘争に参加している人は誰もいない。

カテゴリ:  qt プロジェクトのケース 、  qt の古典的な記事 、  qt 学習のケース 、 カスタム コントロール

おすすめ

転載: blog.csdn.net/qq_30392343/article/details/127582384