QT5.14.2 官方例子 - Qt Widgets 9: painting\affine(仿射)

系列总链接:

QT5.14.2 官方例子 - 学习系列

https://blog.csdn.net/qq_22122811/article/details/108007519

 

项目位置:

Examples\Qt-5.14.2\widgets\painting\affine

注:在Examples下的路径

项目模块:widgets\painting

 

项目描述:

演示了QPainter中仿射变换的工作原理。(图片,文字进行大小,旋转)

项目效果:

 

官网讲解:

Affine Transformations | Qt Widgets 5.14.2

https://doc.qt.io/qt-5.14/qtwidgets-painting-affine-example.html

 

可以在使用QPainter绘制的任何类型的图形上执行转换。用于显示矢量图形、图像和文本的转换可以通过以下方式进行调整:

拖动每幅画中心的红色圆,将其移动到一个新的位置。

拖动移位的红色圆将导致当前绘图围绕中心圆旋转。旋转也可以通过旋转滑块控制。

缩放由缩放滑块控制。

每条图纸都可以用剪切滑块进行剪切。

 

思路解析:

1.布局:

左边为:XFormView,其继承于ArthurFrame,ArthurFrame继承于QWidget

右边为:QGroupBox对象;

    QHBoxLayout *viewLayout = new QHBoxLayout(this);
    viewLayout->addWidget(view);
    viewLayout->addWidget(mainGroup);

 

逻辑理解:

1.初始化显示的状态,左边展示图片,矢量图,文字等的变化,右边为具体设置项

XFormWidget::XFormWidget(QWidget *parent)
    : QWidget(parent), textEditor(new QLineEdit)
{
    setWindowTitle(tr("Affine Transformations"));

    // 创建左侧XFormView视图对象
    view = new XFormView(this);
    view->setMinimumSize(200, 200);

    // 创建右侧Affine Transformations, Type, Others btn的布局
    QGroupBox *mainGroup = new QGroupBox(this);
    mainGroup->setFixedWidth(180);
    mainGroup->setTitle(tr("Affine Transformations"));

    QGroupBox *rotateGroup = new QGroupBox(mainGroup);
    rotateGroup->setTitle(tr("Rotate"));
    QSlider *rotateSlider = new QSlider(Qt::Horizontal, rotateGroup);
    rotateSlider->setRange(0, 3600);
    rotateSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);

    QGroupBox *scaleGroup = new QGroupBox(mainGroup);
    scaleGroup->setTitle(tr("Scale"));
    QSlider *scaleSlider = new QSlider(Qt::Horizontal, scaleGroup);
    scaleSlider->setRange(1, 4000);
    scaleSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);

    QGroupBox *shearGroup = new QGroupBox(mainGroup);
    shearGroup->setTitle(tr("Shear"));
    QSlider *shearSlider = new QSlider(Qt::Horizontal, shearGroup);
    shearSlider->setRange(-990, 990);
    shearSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);

    QGroupBox *typeGroup = new QGroupBox(mainGroup);
    typeGroup->setTitle(tr("Type"));
    QRadioButton *vectorType = new QRadioButton(typeGroup);
    QRadioButton *pixmapType = new QRadioButton(typeGroup);
    QRadioButton *textType= new QRadioButton(typeGroup);
    vectorType->setText(tr("Vector Image"));
    pixmapType->setText(tr("Pixmap"));
    textType->setText(tr("Text"));

    QPushButton *resetButton = new QPushButton(mainGroup);
    resetButton->setText(tr("Reset Transform"));

    QPushButton *animateButton = new QPushButton(mainGroup);
    animateButton->setText(tr("Animate"));
    animateButton->setCheckable(true);

    QPushButton *showSourceButton = new QPushButton(mainGroup);
    showSourceButton->setText(tr("Show Source"));
#if QT_CONFIG(opengl)
    QPushButton *enableOpenGLButton = new QPushButton(mainGroup);
    enableOpenGLButton->setText(tr("Use OpenGL"));
    enableOpenGLButton->setCheckable(true);
    enableOpenGLButton->setChecked(view->usesOpenGL());
#endif
    QPushButton *whatsThisButton = new QPushButton(mainGroup);
    whatsThisButton->setText(tr("What's This?"));
    whatsThisButton->setCheckable(true);

    QHBoxLayout *viewLayout = new QHBoxLayout(this);
    viewLayout->addWidget(view);
    viewLayout->addWidget(mainGroup);

    QVBoxLayout *rotateGroupLayout = new QVBoxLayout(rotateGroup);
    rotateGroupLayout->addWidget(rotateSlider);

    QVBoxLayout *scaleGroupLayout = new QVBoxLayout(scaleGroup);
    scaleGroupLayout->addWidget(scaleSlider);

    QVBoxLayout *shearGroupLayout = new QVBoxLayout(shearGroup);
    shearGroupLayout->addWidget(shearSlider);

    QVBoxLayout *typeGroupLayout = new QVBoxLayout(typeGroup);
    typeGroupLayout->addWidget(vectorType);
    typeGroupLayout->addWidget(pixmapType);
    typeGroupLayout->addWidget(textType);
    typeGroupLayout->addSpacing(4);
    typeGroupLayout->addWidget(textEditor);

    QVBoxLayout *mainGroupLayout = new QVBoxLayout(mainGroup);
    mainGroupLayout->addWidget(rotateGroup);
    mainGroupLayout->addWidget(scaleGroup);
    mainGroupLayout->addWidget(shearGroup);
    mainGroupLayout->addWidget(typeGroup);
    mainGroupLayout->addStretch(1);
    mainGroupLayout->addWidget(resetButton);
    mainGroupLayout->addWidget(animateButton);
    mainGroupLayout->addWidget(showSourceButton);
#if QT_CONFIG(opengl)
    mainGroupLayout->addWidget(enableOpenGLButton);
#endif
    mainGroupLayout->addWidget(whatsThisButton);

    connect(rotateSlider, &QSlider::valueChanged, view, &XFormView::changeRotation);
    connect(shearSlider, &QSlider::valueChanged, view, &XFormView::changeShear);
    connect(scaleSlider, &QSlider::valueChanged, view, &XFormView::changeScale);

    connect(vectorType, &QRadioButton::clicked, view, &XFormView::setVectorType);
    connect(pixmapType, &QRadioButton::clicked, view, &XFormView::setPixmapType);
    connect(textType, &QRadioButton::clicked, view, &XFormView::setTextType);
    connect(textType, &QRadioButton::toggled, textEditor, &XFormView::setEnabled);
    connect(textEditor, &QLineEdit::textChanged, view, &XFormView::setText);

    // 如果左边视图释放"旋转,大小,断裂"改变的信号,则对应的滑块得跟着变更匹配的值
    // 加&是表示传递的是信号(槽)的地址
    connect(view, &XFormView::rotationChanged, rotateSlider, &QSlider::setValue);
    connect(view, &XFormView::scaleChanged, scaleSlider, &QAbstractSlider::setValue);
    connect(view, &XFormView::shearChanged, shearSlider, &QAbstractSlider::setValue);

    connect(resetButton, &QPushButton::clicked, view, &XFormView::reset);
    connect(animateButton, &QPushButton::clicked, view, &XFormView::setAnimation);
    // 如果点击"what's this",则view描述使能打开,支持文本说明
    connect(whatsThisButton, &QPushButton::clicked, view, &ArthurFrame::setDescriptionEnabled);

    // 矢量点不是当前类区域定义的对象,需要通过view->hoverPoints(),以成员(view)的成员(view->hoverPoints())的形式联系起来
    // 如果点击"what's this",则令萦绕点向量不显示(setDiabled),因为太丑了。。。
    connect(whatsThisButton, &QPushButton::clicked, view->hoverPoints(), &HoverPoints::setDisabled);
    // view使能描述改变,匹配改变萦绕点向量显示更改
    connect(view, &XFormView::descriptionEnabledChanged, view->hoverPoints(), &HoverPoints::setDisabled);
    // view使能描述改变,匹配改变"what's this"状态更改
    connect(view, &XFormView::descriptionEnabledChanged, whatsThisButton, &QPushButton::setChecked);
    connect(showSourceButton, &QPushButton::clicked, view, &XFormView::showSource);
#if QT_CONFIG(opengl)
    connect(enableOpenGLButton, &QPushButton::clicked, view, &XFormView::enableOpenGL);
#endif

    // view加载需要显示的源文件
    view->loadSourceFile(":res/affine/xform.cpp");
    // view加载需要显示的网页
    view->loadDescription(":res/affine/xform.html");

    // defaults
    view->reset();
    vectorType->setChecked(true);
    textEditor->setText("Qt Affine Transformation Example");
    textEditor->setEnabled(false);

    // animateClick和click的区别:
    // 执行动画点击:立即按下按钮,并在毫秒之后释放(默认是100毫秒)。
    // 在释放按钮之前再次调用此函数将重置释放计时器。
    // 与单击关联的所有信号都会相应地发出。
    animateButton->animateClick();
}

最后由animateButton执行槽函数animateClick(),左侧视图开启动态展示,右侧滑块动态滑动,等等;

 

2.点击: 下面的三个slider(滑块),分别实现图片的旋转,缩放,拉拽:

代码:XFormWidget类中:

changeRotation:更改旋转

changeShear:更改断裂

changeScale:更改大小,比例

    connect(rotateSlider, &QSlider::valueChanged, view, &XFormView::changeRotation);
    connect(shearSlider, &QSlider::valueChanged, view, &XFormView::changeShear);
    connect(scaleSlider, &QSlider::valueChanged, view, &XFormView::changeScale);

=》

slider滑动,XFormView类中,执行相应槽 :

void XFormView::changeRotation(int r)
{
    setRotation(qreal(r) / 10);
}

void XFormView::changeScale(int s)
{
    setScale(qreal(s) / 1000);
}

void XFormView::changeShear(int s)
{
    setShear(qreal(s) / 1000);
}

=》

void XFormView::setShear(qreal s)
{
    m_shear = s;
    update();
}

void XFormView::setScale(qreal s)
{
    m_scale = s;
    update();
}

void XFormView::setRotation(qreal r)
{
    qreal old_rot = m_rotation;
    m_rotation = r;

    QPointF center(pts->points().at(0));
    QMatrix m;
    m.translate(center.x(), center.y());
    m.rotate(m_rotation - old_rot);
    m.translate(-center.x(), -center.y());
    pts->setPoints(pts->points() * m);

    update();
}
void XFormView::paint(QPainter *p)
{
    // 保存当前绘画家指针入堆(stack)
    p->save();
    //p->setRenderHint(QPainter::Antialiasing);
    // 表示引擎应该使用平滑的像素图转换算法(如双线性)而不是最近邻算法。
    //p->setRenderHint(QPainter::SmoothPixmapTransform);

    // 根据当前类型绘画图形,文本
    switch (m_type) {
    case VectorType:
        drawVectorType(p);
        break;
    case PixmapType:
        drawPixmapType(p);
        break;
    case TextType:
        drawTextType(p);
        break;
    }

    // 使绘画家指针出堆(stack)
    p->restore();
}

=》

drawVectorType(QPainter* painter): 绘制向量类型图

drawTextType(QPainter *painter): 绘制文本类型

drawPixmapType(QPainter *painter): 绘制图片

对上述绘制过程的详细分析,暂时不进以深入,等后续有需要再进行深入。。。

 

函数积累:

1.QList<T> QObject::findChildren(const QString &name = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const

介绍:返回具有给定名称的此对象的所有可转换为T类型的子对象,或者如果没有这样的对象,返回一个空列表。。。。

    XFormWidget xformWidget(nullptr);
    QStyle *arthurStyle = new ArthurStyle;
    xformWidget.setStyle(arthurStyle);
    
    // 获取xformWidget的子控件列表
    const QList<QWidget *> widgets = xformWidget.findChildren<QWidget *>();
    for (QWidget *w : widgets) 
    {
        // 设置每个子控件的风格
        w->setStyle(arthurStyle);
        // 设置接受触摸事件
        w->setAttribute(Qt::WA_AcceptTouchEvents);
    }

 

类积累:

1.QStyle

QStyle类是一个抽象基类,它封装了GUI的外观和感觉

具体使用可参考:

https://blog.csdn.net/wangyanphp/article/details/38532801

三种方法来重新定义Qt内置窗口部件的外观:
1)子类化QStyle或者一个预定义的风格,这种方法很好用,Qt本身就是用这种方法为它所支持的不同平台提供基于平台的外观的

2)子类化个别的窗口部件类,并且重新实现它的绘制和鼠标事件处理器。

3)Qt 样式表

 

2.QGroupbox

QGroupBox为构建分组框提供了支持。分组框通常带有一个边框和一个标题栏,作为容器部件来使用,在其中可以布置各种窗口部件。布局时可用作一组控件的容器,但是需要注意的是,内部必须使用布局控件(如QBoxLayout)进行布局。

QGroupBox继承关系:

 

其他积累:

Q_PROPERTY:Qt自有的属性结构,

Qt中类的属性是给脚本和元对象系统用的,比如QtScript,QML,或者QObject::property/setProperty……,主要就是用来进行属性封装,在具体的脚本,库,qml开发中必须使用。

 

具体可查看:http://note.youdao.com/noteshare?id=10ee53b525aa40f8f52290cf819b798e&sub=834CE6B6B0464B6FBC547426ACBECB20

举一反三:

 

借鉴思路:

1.对图片大小的处理;

2.对图片旋转的思路;

3.对图片进行拉拽的思路;

4.图片动画效果;

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Command line: -prefix /home/liuyh/workspace/qt5.14.2-arm -opensource -confirm-license -release -strip -shared -xplatform linux-arm-gnueabi-g++ -optimized-qmake -c++std c++11 --rpath=no -pch -skip qt3d -skip qtactiveqt -skip qtandroidextras -skip qtcanvas3d -skip qtconnectivity -skip qtdatavis3d -skip qtdoc -skip qtgamepad -skip qtlocation -skip qtmacextras -skip qtnetworkauth -skip qtpurchasing -skip qtremoteobjects -skip qtscript -skip qtscxml -skip qtsensors -skip qtspeech -skip qtsvg -skip qttools -skip qttranslations -skip qtwayland -skip qtwebengine -skip qtwebview -skip qtwinextras -skip qtx11extras -skip qtxmlpatterns -make libs -make examples -nomake tools -nomake tests -gui -widgets -dbus-runtime --glib=no --iconv=no --pcre=qt --zlib=qt -no-openssl --freetype=qt --harfbuzz=qt -no-opengl -linuxfb --xcb=no -tslib --libpng=qt --libjpeg=qt --sqlite=qt -plugin-sql-sqlite -I/opt/tslib/include -L/opt/tslib/lib -recheck-all executing config test machineTuple + arm-linux-gnueabi-g++ -dumpmachine > sh: 1: arm-linux-gnueabi-g++: not found test config.qtbase.tests.machineTuple FAILED executing config test verifyspec + cd /home/liuyh/workspace/QT5.14.2/qt-everywhere-src-5.14.2/config.tests/verifyspec && /home/liuyh/workspace/QT5.14.2/qt-everywhere-src-5.14.2/qtbase/bin/qmake "CONFIG -= qt debug_and_release app_bundle lib_bundle" "CONFIG += shared warn_off console single_arch" 'QMAKE_LIBDIR += /opt/tslib/lib' 'INCLUDEPATH += /opt/tslib/include' -early "CONFIG += cross_compile" /home/liuyh/workspace/QT5.14.2/qt-everywhere-src-5.14.2/qtbase/config.tests/verifyspec + cd /home/liuyh/workspace/QT5.14.2/qt-everywhere-src-5.14.2/config.tests/verifyspec && MAKEFLAGS= /usr/bin/make clean && MAKEFLAGS= /usr/bin/make > rm -f verifyspec.o > rm -f *~ core *.core > arm-linux-gnueabi-g++ -c -O2 -march=armv7-a -mtune=cortex-a7 -mfpu=neon -mfloat-abi=hard -O2 -march=armv7-a -mtune=cortex-a7 -mfpu=neon -mfloat-abi=hard -pipe -O2 -w -fPIC -I/home/liuyh/workspace/QT5.14.2/qt-everywhere-src-5.14.2/qtbase/config.tests/verifyspec -I. -I/opt/tslib/include -I/home/liuyh/workspace/QT5.14.2/qt-everywhere-src-5.14.2/qtbase/mkspecs/linux-arm-gnueabi-g++ -o verifyspec.o /home/liuyh/workspace/QT5.14.2/qt-everywhere-src-5.14.2/qtbase/config.tests/verifyspec/verifyspec.cpp > make:arm-linux-gnueabi-g++:命令未找到 > make: *** [Makefile:172:verifyspec.o] 错误 127
06-09

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值