欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Qt项目中,用QPainter进行绘制图形时,边角显示不完整问题的梳理

程序员文章站 2022-03-21 19:26:48
总第42篇 本文主要梳理总结了我自己在项目开发过程中经常遇到的一个问题,就是用QPainter进行图形绘制时,边角显示不完整的现象。这个问题虽然比较简单,但是很容易忘记,每次绘图时都要调试一下,故总结于此,方便以后查阅,也方便同行伙伴参考。 1.Painter绘制 我们知道,QPainter简直是王者,任何图形都可以由它绘制出来。 ......

总第42篇

本文主要梳理总结了我自己在项目开发过程中经常遇到的一个问题,就是用QPainter进行图形绘制时,边角显示不完整的现象。这个问题虽然比较简单,但是很容易忘记,每次绘图时都要调试一下,故总结于此,方便以后查阅,也方便同行伙伴参考。

1.Painter绘制

我们知道,QPainter简直是王者,任何图形都可以由它绘制出来。

Qt项目中,用QPainter进行绘制图形时,边角显示不完整问题的梳理

如上图所示,项目中在制作这个页面时,我们会将每个部分制作成一个单独的控件,这个控件继承于QPushButton类,并重写void resizeEvent(QResizeEvent *event)void paintEvent(QPaintEvent *event)两个函数,其中前者主要获取并设定这个控件中图标文字的相对位置,后者要主负责对控件重新绘制。

在类的初始化时,要设定可选中属性:setFocusPolicy(Qt::StrongFocus)

下面将其主要代码放在下面:

        void QToolItem::resizeEvent(QResizeEvent *event)
{
     //获取相关的矩形区域、边框圆角和线宽等
     ......
     //初始化路径
     m_btnPath = QPainterPath();
     m_btnPath.setFillRule(Qt::WindingFill);
     m_btnPath.addRoundedRect(rect(), m_corner, m_corner);

     //最后调用父类的resizeEvent
     QPushButton::resizeEvent(event);
}

void QToolItem::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.save();
    painter.setRenderHints(QPainter::Antialiasing, true);   //打开防锯齿

    //若选中状态时,绘制边框
    if(hasFocus())
    {
        painter.fillPath(m_btnPath, m_clrSelectedBk);   //先填充路径
        painter.setPen(QPen(m_clrBorder, m_borderWidth));
        painter.drawRoundedRect(rect().adjusted(1,1,-1,-1), m_corner, m_corner);  //再画边框
    }
    else
    {
        painter.fillPath(m_btnPath, m_clrResetBk);
    }
    painter.setRenderHints(QPainter::Antialiasing, false);   //关闭反走样

    //画图标
    QString tempPicture = m_strPixPath;
    if(!tempPicture.isEmpty())
    {
        if(!m_isRunning)
            tempPicture += "_1.png";
        else
            tempPicture += "_2.png";
        painter.drawImage(m_rectMap, QImage(tempPicture));
    }
    //画标题文字
    painter.setFont(m_ftTitle);
    if(!m_isRunning)
        painter.setPen(m_clrTitleReset);
    else
        painter.setPen(m_clrTitleStart);
    painter.drawText(m_rectTitle, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap, m_strTitle);

    //画描述文字
    painter.setFont(m_ftDesc);
    painter.setPen(m_clrDesc);
    painter.drawText(m_rectDesc, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, m_strDesc);

    painter.restore();

      

这里在绘制圆角矩形区域时,一定要注意,要先填充区域后,再绘制边框。若先绘制边框,再填充区域,会导致边框线看不到,只能显示四个圆角处的点线。

另一个比较重要的点是,在绘制边框时,若直接使用这句:

         painter.drawRoundedRect(rect(), m_corner, m_corner);

      

则会导致线很细,即使你加粗了线宽,也不是很明显。为什么会这样呢?这是因为painter在绘制时都是从0像素开始的,例如,若要绘制100的长度,它实际绘制的是从099像素。因此,我们设置边框线宽为2时,其可见的也只有一个像素。我们可以修改一下,用下面这句:

        painter.drawRoundedRect(rect().adjusted(1,1,-1,-1), m_corner, m_corner);

      

这相当于是将画边框的位置略微向内移动了一个像素,即可得到完美的效果。

另外,对于绘制图形时,反走样特性,不能随便开,绘制完成后要记得随手关闭。在绘制直线时,不要打开反走样特性,否则,直线绘制显示会很模糊。

2.Layout布局

对于上面项目中的控件,若不绘制的话,也可以通过布局实现,你可根据自己的开发场景选择。其示例代码如下:

            QLabel* label = new QLabel();
    QLabel* label2 = new QLabel();
    label2->setStyleSheet(QString("border:1px solid red;"));
    label->setStyleSheet(QString("border:1px solid red;"));
    label2->setPixmap(QPixmap("E:/QtCode/QPushbuttonPaintIcon/upgrade.png"));
    label->setText("升级工具");
    label->setFixedWidth(80);
    QHBoxLayout* myLayout = new QHBoxLayout();
    myLayout->addSpacing(10);
    myLayout->addWidget(label2);
    myLayout->addSpacing(30);
    myLayout->addWidget(label);
    myLayout->addStretch();
    ui->pushButton->setLayout(myLayout);

      

本文到此结束!

如果对你有帮助,请随手 点赞点喜欢

=======================================================

欢迎【关注、私信 @武三郎。我们一起交流一起进步。

本文地址:https://blog.csdn.net/huixieqingchun/article/details/107380308

相关标签: java