我有一个Qt应用程序,想展示一个小教程,当用户第一次访问该应用程序。是这样的:
我怎么能在Qt上做这样的事情呢? 我在Windows上使用Qt 5.4。 问题来源StackOverflow 地址:/questions/59380260/pyside-how-can-i-fade-the-edges-of-a-widget-into-the-background
为了执行这个任务,我们必须创建半透明的背景,我们通过激活属性Qt::WA_TranslucentBackground来实现,然后我们使用QPainterPath来绘制矩形减去透明圆。 然后使用eventFilter来了解一些事件,比如当您更改大小或位置时显示的事件。 然后创建一个结构来存储数据,在本例中是圆的中心、半径、文本的位置和文本本身。 然后添加next和return按钮,并在插槽中处理页面更改的逻辑。 tutowidget.h
#ifndef TUTOWIDGET_H
#define TUTOWIDGET_H
#include <QWidget>
class QButtonGroup;
class TutoWidget : public QWidget
{
Q_OBJECT
struct Pages{
QPoint center;
int radius;
QPoint pText;
QString text;
};
public:
TutoWidget(QWidget *parent);
void addPage(const QPoint ¢er, int radius, const QPoint &pText, const QString & text);
bool eventFilter(QObject *watched, QEvent *event);
protected:
void paintEvent(QPaintEvent *);
private slots:
void onClicked(int id);
private:
QWidget *mParent;
QButtonGroup *group;
QVector<Pages> pages;
int currentIndex = -1;
};
#endif // TUTOWIDGET_H
tutowidget.cpp
#include "tutowidget.h"
#include <QVBoxLayout>
#include <QButtonGroup>
#include <QPushButton>
#include <QEvent>
#include <QTimer>
#include <QPainter>
TutoWidget::TutoWidget(QWidget *parent):QWidget(0)
{
setWindowFlags(Qt::FramelessWindowHint|Qt::Popup);
setAttribute(Qt::WA_TranslucentBackground, true);
mParent = parent;
mParent->installEventFilter(this);
QVBoxLayout *vlay = new QVBoxLayout(this);
vlay->addItem(new QSpacerItem(20, 243, QSizePolicy::Minimum, QSizePolicy::Expanding));
QHBoxLayout *hlay = new QHBoxLayout;
vlay->addLayout(hlay);
group = new QButtonGroup(this);
const QStringList nameBtns{"Return", "Next"};
for(int i=0; i < nameBtns.length(); i++){
QPushButton* btn = new QPushButton(nameBtns[i]);
btn->setFlat(true);
group->addButton(btn, i);
hlay->addWidget(btn);
}
connect(group, static_cast<void (QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked),
this, static_cast<void (TutoWidget::*)(int)>(&TutoWidget::onClicked));
hlay->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));
group->button(0)->hide();
}
void TutoWidget::addPage(const QPoint ¢er, int radius, const QPoint &pText, const QString &text)
{
pages << Pages{center, radius, pText, text};
if(currentIndex == -1){
currentIndex = 0;
update();
}
}
bool TutoWidget::eventFilter(QObject *watched, QEvent *event){
if(watched == mParent){
switch (event->type()) {
case QEvent::Show:
QTimer::singleShot(10, this, &QWidget::show);
break;
case QEvent::Close:
close();
break;
case QEvent::Move:
move(mParent->mapToGlobal(QPoint(0, 0)));
break;
case QEvent::Resize:
resize(mParent->size());
break;
default:
break;
}
}
return QWidget::eventFilter(watched, event);
}
void TutoWidget::paintEvent(QPaintEvent *){
QPainter painter(this);
painter.setPen(Qt::NoPen);
painter.setRenderHint(QPainter::Antialiasing);
painter.setBrush(QColor(100, 100, 100, 200));
QPainterPath path;
if(currentIndex != -1){
QPoint center = pages[currentIndex].center;
int radius = pages[currentIndex].radius;
QString text = pages[currentIndex].text;
QPoint pText = pages[currentIndex].pText;
path.moveTo(center + radius/2*QPoint(1, 0));
path.arcTo(QRect(center-radius/2*QPoint(1, 1),radius*QSize(1, 1)), 0, 360);
path.addText(pText, font(), text);
}
path.addRect(rect());
painter.drawPath(path);
}
void TutoWidget::onClicked(int id)
{
if(id == 0){
if(currentIndex > 0)
currentIndex--;
}
else if(id == 1){
if(currentIndex < pages.count()-1)
currentIndex++;
}
update();
group->button(0)->setVisible(currentIndex!=0);
group->button(1)->setVisible(currentIndex!=(pages.count()-1));
}
例子:
tuto = new TutoWidget(this); // this is the widget
tuto->addPage(QPoint(200, 200), 40, QPoint(100, 100), "some text1");
tuto->addPage(QPoint(300, 300), 60, QPoint(200, 100), "some text2");
tuto->addPage(QPoint(100, 200), 100, QPoint(200, 50), "some text3");
tuto->addPage(QPoint(200, 100), 80, QPoint(100, 200), "some text4");
完整的示例在下面的链接中
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。