开发者社区> 问答> 正文

创建教程模式

我有一个Qt应用程序,想展示一个小教程,当用户第一次访问该应用程序。是这样的:

我怎么能在Qt上做这样的事情呢? 我在Windows上使用Qt 5.4。 问题来源StackOverflow 地址:/questions/59380260/pyside-how-can-i-fade-the-edges-of-a-widget-into-the-background

展开
收起
kun坤 2019-12-28 14:25:11 592 0
1 条回答
写回答
取消 提交回答
  • 为了执行这个任务,我们必须创建半透明的背景,我们通过激活属性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 &center, 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 &center, 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");
    

    完整的示例在下面的链接中

    2019-12-28 14:25:19
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
内容驱动游戏分发 立即下载
动态、高效,蚂蚁动态卡片的内核逻辑 立即下载
函数计算最佳实践:快速开发一个分布式 Puppeteer 网页截图服务 立即下载