效果图
源代码
widget.h文件源代码
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QLabel>
#include <QVariantAnimation>
#include <QTimer>
#include <array>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
protected:
void paintEvent(QPaintEvent* e);
private slots:
void on_pushButton_clicked();
void do_valueChanged(const QVariant& var);
void on_btnPause_clicked();
void on_btnClear_clicked();
private:
Ui::Widget *ui;
std::array<QPoint,6> points;
QTimer* timer;
QPoint m_point;
QVariantAnimation* variantAnimation;
QRadialGradient radial;
int times = 0;//次数
};
#endif // WIDGET_H
widget.cpp源代码
#include "widget.h"
#include "./ui_widget.h"
#include <QPainter>
#include <QRadialGradient>
#include <thread>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
int len = 6;
this->setGeometry(0,0,600,200);
variantAnimation = new QVariantAnimation(this);
variantAnimation->setStartValue(QPointF(50,100));
variantAnimation->setEndValue(QPointF(600,100));
variantAnimation->setDuration(2000);
radial.setCenterRadius(50);
radial.setFocalPoint(QPoint(60,20));
radial.setFocalRadius(10);
radial.setSpread(QGradient::ReflectSpread);
timer = new QTimer(this);
timer->setTimerType(Qt::PreciseTimer);
timer->setInterval(2000);
connect(timer,&QTimer::timeout,this,[=](){
qDebug()<<"animation started";
times+=1;
if(times%2==0)
variantAnimation->setDirection(QVariantAnimation::Backward);
else
variantAnimation->setDirection(QVariantAnimation::Forward);
variantAnimation->start();
});
connect(variantAnimation,&QVariantAnimation::valueChanged,this,&Widget::do_valueChanged);
}
void Widget::do_valueChanged(const QVariant& var)
{
m_point = var.toPoint();
// qDebug()<<"current point:"<<m_point;
this->update();
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent* e)
{
//重写绘制事件
QPainter painter;
if(!painter. Begin(this))
{
qWarning("painter begin fail");
return QWidget::paintEvent(e);
}
painter.setRenderHints(QPainter::TextAntialiasing|QPainter::Antialiasing);
painter.setViewport(this->rect());
radial.setCenter(m_point);
radial.setColorAt(0,QColor(240,240,240));
radial.setColorAt(1,QColor(250,250,250));
QPen pen;
pen.setStyle(Qt::NoPen);
painter.setPen(pen);
painter.fillRect(painter.window(),QBrush(radial));
if(!painter.end())
{
qWarning("painter end fail");
return QWidget::paintEvent(e);
}
return QWidget::paintEvent(e);
};
void Widget::on_pushButton_clicked()
{
timer->start();
}
void Widget::on_btnPause_clicked()
{
variantAnimation->pause();
QPoint currentValue = variantAnimation->currentValue().toPoint();
QList<QLabel*> labels = this->findChildren<QLabel*>();
for(auto& label:labels)
{
QPoint topLeft = label->rect().topLeft();
QPoint bottomRight = label->rect().bottomRight();
QPoint parentTopLeft = label->mapToParent(topLeft);
QPoint parentBottomRight = label->mapToParent(bottomRight);
QRect parentRect(parentTopLeft,parentBottomRight);
qDebug()<<"parent rect:"<<parentRect;
if(parentRect.contains(currentValue))
{
// label->setText("你抓到我了!");
label->hide();
}
}
std::this_thread::sleep_for(std::chrono::seconds(1));
variantAnimation->resume();
}
void Widget::on_btnClear_clicked()
{
//重置游戏
QList<QLabel*> labels = this->findChildren<QLabel*>();
for(auto label:labels)
{
label->show();
}
}
main.cpp源代码
#include "widget.h"
#include <QApplication>
#include <QLocale>
#include <QTranslator>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTranslator translator;
const QStringList uiLanguages = QLocale::system().uiLanguages();
for (const QString &locale : uiLanguages) {
const QString baseName = "RadioGradient_" + QLocale(locale).name();
if (translator.load(":/i18n/" + baseName)) {
a.installTranslator(&translator);
break;
}
}
Widget w;
w.show();
return a.exec();
}
cmakeList.txt 源代码
cmake_minimum_required(VERSION 3.5)
project(RadioGradient VERSION 0.1 LANGUAGES CXX)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets LinguistTools)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets LinguistTools)
set(TS_FILES RadioGradient_zh_CN.ts)
set(PROJECT_SOURCES
main.cpp
widget.cpp
widget.h
widget.ui
${TS_FILES}
)
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
qt_add_executable(RadioGradient
MANUAL_FINALIZATION
${PROJECT_SOURCES}
)
# Define target properties for Android with Qt 6 as:
# set_property(TARGET RadioGradient APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
# ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
else()
if(ANDROID)
add_library(RadioGradient SHARED
${PROJECT_SOURCES}
)
# Define properties for Android with Qt 5 after find_package() calls as:
# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
else()
add_executable(RadioGradient
${PROJECT_SOURCES}
)
endif()
qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
endif()
target_link_libraries(RadioGradient PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
if(${QT_VERSION} VERSION_LESS 6.1.0)
set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.RadioGradient)
endif()
set_target_properties(RadioGradient PROPERTIES
${BUNDLE_ID_OPTION}
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)
include(GNUInstallDirs)
install(TARGETS RadioGradient
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
if(QT_VERSION_MAJOR EQUAL 6)
qt_finalize_executable(RadioGradient)
endif()
widget.ui 文件
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>698</width>
<height>194</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Widget</string>
</property>
<property name="styleSheet">
<string notr="true">QWidget
{
background-color:transparent
}</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="1">
<widget class="QLabel" name="label2">
<property name="text">
<string>箱子2</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label1">
<property name="text">
<string>箱子1</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="label4">
<property name="text">
<string>箱子4</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QLabel" name="label5">
<property name="text">
<string>箱子5</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label3">
<property name="text">
<string>箱子3</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QLabel" name="label6">
<property name="text">
<string>箱子6</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>发射</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="btnPause">
<property name="text">
<string>抓取</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="btnClear">
<property name="text">
<string>清空</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>