Qt中绘制蚂蚁线

提要

如果有用过PS的选区工具应该就会知道蚂蚁线是什么东西了,就是用来表示选区的一种虚线,关键还是要动态的!

Qt 中自带的一个例子就有各种描边的演示,但是最终达到的效果只能是一个静态的描边,根本不够炫酷,So.还是自己来实现以下。

先看下最终的结果:

是可以动起来的哈,只不过截图是静态的。最终实现的效果和PS中的选区工具完全一样。

分析

输入

一个QRect

输出

动态的黑白相间的蚂蚁线描边。(注意是黑色和白色,不是黑色和透明)

解决方案

创建一个画布大小的QImage,然后找到边缘的像素,挨个填充像素。最后用painter.drawImage将这个Image绘制在最上面就可以了。

动画的效果通过QTimer,设定一个计时器,然后不断repaint就可以了。

代码实现

头文件中声明一些成员变量

int borderOffset;
bool isBlackStart;
QTimer *repaintTimer;

计时器的初始化

repaintTimer = new QTimer();
repaintTimer->setInterval(380);
repaintTimer->start();
connect(repaintTimer, SIGNAL(timeout()), this, SLOT(updateSelectionBorder()));

对应的槽函数

void Canvas::updateSelectionBorder()
{
	borderOffset++;
	if (borderOffset > 4)
	{
		borderOffset = 0;
		isBlackStart = !isBlackStart;
	}
	this->repaint();
}

最最重要的绘制边框函数

void Canvas::paintSelectionBorder(QPainter &painter)
{
	int startX = selectionRect.startPoint().x();
	int startY = selectionRect.startPoint().y();

	//Init a transparent QImage.
	QSize scaledSize = m_scaleFactor * m_image.size();
	QImage transparentImage(scaledSize, QImage::Format_ARGB32);

	QColor transparent(0, 0, 0, 0);
	QColor black(0, 0, 0);
	QColor white(255, 255, 255);

	for (int i = 0; i < scaledSize.width(); i++)
		for (int j = 0; j < scaledSize.height(); j++)
		{
			transparentImage.setPixel(i, j, transparent.rgba());
		}

	bool isDrawBlack = true;

	//Draw left&right border.
	for (int i = 0; i < selectionRect.height(); i++)
	{
		if (i <=  borderOffset)
		{
			transparentImage.setPixel(startX + selectionRect.width(), startY + i, isBlackStart ? black.rgb() : white.rgb());
			transparentImage.setPixel(startX, startY + i, isBlackStart ? black.rgb() : white.rgb());
			isDrawBlack = !isBlackStart;
		}
		else
		{
			transparentImage.setPixel(startX + selectionRect.width(), startY + i, 				isDrawBlack ? black.rgb() : white.rgb());
			transparentImage.setPixel(startX, startY + i, 				isDrawBlack ? black.rgb() : white.rgb());
			if ((i - borderOffset) % 5 == 0)
			{
				isDrawBlack = !isDrawBlack;
			}
		}
	}

	//Draw top&bottom border;
	for (int i = 0; i < selectionRect.width(); i++)
	{
		if (i <= borderOffset)
		{
			transparentImage.setPixel(startX+i, startY, isBlackStart ? black.rgb() : white.rgb());
			transparentImage.setPixel(startX + i, startY + selectionRect.height(), isBlackStart ? black.rgb() : white.rgb());

			isDrawBlack = !isBlackStart;
		}
		else
		{
			transparentImage.setPixel(startX + i, startY, 				isDrawBlack ? black.rgb() : white.rgb());
			transparentImage.setPixel(startX + i, startY + selectionRect.height(), 				isDrawBlack ? black.rgb() : white.rgb());
			if ((i - borderOffset) % 5 == 0)
			{
				isDrawBlack = !isDrawBlack;
			}
		}
	}

	painter.drawImage(0, 0, transparentImage);
}

打完收工。

感谢 大自在 大神的指点!

时间: 2024-11-08 16:56:45

Qt中绘制蚂蚁线的相关文章

Qt中绘制五子棋棋盘

一个需要做大作业的同学问我相关内容,就顺手写了一个,贴出来. 项目包含头文件 mainwindowh,源文件mainwindow.cpp和主函数main.cpp. 如下: mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QWidget> #include <QPainter> class MainWindow : public QWidget { Q_OBJECT public: MainWindow

Qt中截图功能的实现

提要 需求:加载一张图片并显示,可以放大缩小,可以截取图片的某个矩形并保存. 原以为蛮简单的一个功能,其实还是有点小复杂. 最简单Qt图片浏览器可以参考Qt自带的Demo:Image Viewer Example 看一下最终的实现效果: 图片的加载显示 这里需要实现一个QImageViewer的类,继承自QWidget. 图片用QPixmap来加载和显示,还有三个成员分别是图片的缩放因子,图片是否已经加载,viewer是否已经初始化,是否处于裁剪状态. private: QPixmap m_pi

qt中窗口绘制——图片的绘制

在qt 中,QPixmap 用于表示一张图片,支持png,jpg格式的加载. QPixmap pm("c:/test.png"); 或者 QPixmap pm; pm.load("c:/test/png"); QT中图片的路径分为两种: (1)文件系统中的图片:使用绝对路径或者相对路径. (2)资源中的文件:以冒号开头例如:/Test/source/logo.jpg 绘制的参数: (1)源矩形 可以绘制图形的全部,也可以绘制其中的一部分. QRect source(

QT中异形窗口的绘制(winEvent处理WM_NCHITTEST消息)

这里讨论的只是Windows平台上的实现. 在QT中绘制异形窗口,只要设定 windowFlag 为 CustomizeWindowHint,再结合setMask()就可以做出各种奇形怪状的窗口.相对来说比较麻烦的, 是进行窗口拖动和缩放的处理. 在 Windows SDK 和 MFC 中比较容易,只要处理 WM_NCHITTEST,返回相应的测试值就可以了.幸运的是,QT中也提供了直接处理各平台消息的方法,在 Windows下只需要重载winEvent方法. 下面给出了示例代码: // inc

第47课 Qt中的调色板

1. QPalette类 (1)QPalette类提供了绘制QWidget组件的不同状态所使用的颜色. (2)QPalette对象包含了3个状态的颜色描述 ①激活颜色组(Active):组件获得焦点使用的颜色搭配方案 ②非激活颜色组(Inactive):组件失去焦点使用的颜色方案 ③失效颜色组(Disabled):组件处于不可用状态使用的颜色方案 2.QPalette类中颜色组用途 (1)QPalette类中的颜色组定义了组细节的颜色值 (2)QPalette::ColorRole中的常量值用于

Qt中如何禁掉所有UI操作以及注意事项(处理各个widget的eventFilter这一层,但是感觉不好,为什么不使用QApplication呢)

刚做完的一个项目,在测试时出现了一个问题:由于多线程的存在,当进行语音识别时:如果用户点击程序界面上的button或者其他接受点击事件后会发出信号的widget时,程序会crash ! 后来尝试着从多线程上去解决,但是比较困难:后来只能从另外一条路来解决,那就是:当语音识别进行时:禁掉一切用户操作! 所谓的禁掉一切UI操作,在手机等手持设备上,尤其是纯触摸屏的设备上,主要就是指的禁止mouse操作!当然了:也可能是禁止键盘操作等.那如何去做这一点呢? 方法:我们可以截获禁止操作的窗口的所有eve

TTF字体基本知识及其在QT中的应用

字体类型 以Windows为例,有4种字体技术: Raster:光栅型,就是用位图来绘制字形(glyph),每个字都以位图形式保存 Vector:矢量型,就是用一系列直线的结束点来表示字形 TrueType:使用一系列直线.曲线和一些提示(hint)命令来绘制字形 Microsoft OpenType:与TrueType一致 因为TrueType等字体的hint能够调节只想的长度和曲线的形状,所以,它能够在不同大小的字体中表现良好.而Raster字体则是跟设备具体分辨率相关,而Vector字体则

细说Qt中的MVC (一)

好久不写博客了,最近写了不少Qt相关的代码,在此总结一下个人对Qt中MVC的一点理解.MVC全称是 Model View Controller,是一种非常非常流行的架构模式,相关MVC具体的,网上已经非常非常详尽了,不赘述了. 关于Qt中的MVC 其实Qt中的MVC并不叫MVC,而是叫“MVD”,Qt中没有Controller的说法,而是使用了另外一种抽象:Delegate (委托),其行为和传统的MVC是相同的.写过C#的同学肯定对delegate就不陌生了,这里delegate的用法就是负责

( 转)浅谈QT中窗口刷新事件

浅谈QT中窗口刷新事件 [日期:2011-06-25] 来源:Linux社区  作者:袁硕 [字体:大 中 小] 经过一个星期的项目初步开发,写此文就开发时遇到的一些常见问题,给出些资料和自己的观点,希望能给其他的初学者或者参赛的选手一点帮助,当然,也算是一种抛砖引玉,大家有什么好的技巧经验什么的,也能多多分享,借助这次比赛,我们共同进步~ 如果大家都是跟我一样,刚刚开始接触QT,开始开发QT的程序,肯定也会有很多不习惯的地方,今天我重点想谈的就是这么一个不习惯的地方——QT中窗口刷新事件. 对