前言
qt安装
- linux下默认安装
qt4
sudo apt install install qt4-dev-tools
开发包
sudo apt install install qtcreator
IDE
sudo apt install install qt4-doc
开发文档
sudo apt install install qt4-qtconfig
配置工具
qt5
sudo apt install qt5-default
sudo apt install qt5-qmake
1.多语言设置
开发环境:vs2015 + Qt
- Qt VS Tools->Create new translation file->产生*.ts文件(在工程Translation Files目录下,根据需要产生不同语言包)
- 选中*.ts文件,右键->lupdate->双击打开->翻译语言包
- 选中*.ts文件,右键->lrelease->产生*.qm文件
static QTranslator translator;
int nLangType = _othersSettings.getLanguage();
if (nLangType == 0)
{
translator.load("./thzterminal_zh.qm");
}
else if(nLangType == 1)
{
translator.load("./thzterminal_HK.qm");
}
else if (nLangType == 2)
{
translator.load("./thzterminal_ru.qm");
}
else
{
// 默认英语
}
this->installTranslator(&translator);
注意:最好默认语言使用英语,其他语言使用语言包翻译,方便管理。代码中需要替换的语言需要写成:QObject::tr("language")
,若前面已声明Q_OBJECT
,则可以直接使用tr("language")
。
2.QQueue使用
QQueue
本身没有长度的限制,使用时注意。在工程中如果不添加长度限制,可能会导致内存异常。
m_mutexSerialize.lock();
m_queueDataContent.enqueue(QDataContent(file));
if (m_queueDataContent.size() > m_nQueueSizeMax)
{
QDataContent data = m_queueDataContent.dequeue();
}
m_mutexSerialize.unlock();
3.detach的使用
涉及类:
QPixmap Class
QPixmap Class
QSharedDataPointer Class
QSharedMemory Class
对于QPixmap
类,内部使用cache(载入同一路径的同一文件,下次直接从cache中获取)和隐式共享两种技术,在使用图像拷贝时,图像拷贝后记得image.detach()
释放共享缓存,否则后续不能对拷贝后的图像对象进行操作。
附上,马赛克函数中,图像拷贝时使用的detach操作
void mosaic(QImage& image, const QRect& region, const int size)
{
tcom::Q2DArray<unsigned char> temp(image.height(), image.width()*image.depth() / 8);
memcpy(temp.buffer(), image.bits(), sizeof(unsigned char)*image.width()*image.height()*image.depth() / 8);
// 选择size*size像素区域的第一个像素
int b, g, r, a;
for (int row = region.top(); row < region.top() + region.height();)
{
for (int col = region.left(); col < region.left() + region.width();)
{
if ((row - region.top()) % size == 0 && (col - region.left()) % size == 0)
{
b = temp[row][col * image.depth() / 8];
g = temp[row][col * image.depth() / 8 + 1];
r = temp[row][col * image.depth() / 8 + 2];
a = temp[row][col * image.depth() / 8 + 3];
for (int i = 0; i < size; ++i)
{
for (int j = 0; j < size; ++j)
{
temp[row + i][(col + j) * image.depth() / 8] = b;
temp[row + i][(col + j) * image.depth() / 8 + 1] = g;
temp[row + i][(col + j) * image.depth() / 8 + 2] = r;
temp[row + i][(col + j) * image.depth() / 8 + 3] = a;
}
}
}
col += size;
}
row += size;
}
QImage outImage(temp.buffer(), image.width(), image.height(), QImage::Format_ARGB32);
image = outImage;
image.detach();
}
4.QAtomicInt
多线程共享变量,可能会存储在寄存器中,不能及时得到更新,需要使用QAtomicInt
,将变量保存在内存中,方便及时更新,不至于共享变量已改变,但是寄存器中的变量还没来得及改变,以致程序运行不能达到预期效果。
对于多线程间的互斥资源,使用QMutex
.
5.QImage与QPixmap
QPixmap
:QpaintDevice
类,硬件相关,存储在graphics memory中
QPixmap canvas(rect().width(), rect().height());
QPainter mem(&canvas);
// Qt自带双缓存,此处可以不使用QPixmap(这里相当于增加了一次缓存)
QPainter painter(this);
painter.drawPixmap(0, 0, canvas);
QImage
:图片像素级访问,QpaintDevice
类
painter.drawImage(QRct(0, 0, 148, 408), image);
QPicture
:基类为QPixmap
,QpaintDevice
类,图像深度为1
QBitmap
:基类为QPixmap
,提供单色图像
附加:
QPen
QBrush
6.QImage数据处理
数据读取,数据处理,数据写入
// 方法一
int image2Data(const QImage & image, unsigned char * data, const QString& format, int quality)
{
QByteArray byteArray;
QBuffer buffer(&byteArray);
buffer.open(QIODevice::WriteOnly);
image.save(&buffer, format.toStdString().c_str(), quality);
memcpy(data, byteArray.data(), byteArray.size());
return byteArray.size();
}
// 方法二
# 7.图像处理
## 7.1 QPinter对QPixmap图像拼接、覆盖、写文字
### 7.1.1 一张图片绘制在另一张图片上
```cpp
QPainter painter(&p1);
painter.drawPixmap(0,0,p2.width(),p2.height(), p2);
8.图像黑点
像素级操作图像后,显示图像经常出现极黑的像素点。原因可能有二:
1.若在全是偏白区域中出现黑点,很可能是像素值计算时越界,导致归一化时发生取反的操作;
2.出现干扰性像素值,增加了整幅图像的像素值范围。
void gradation(tcom::Q2DArray<unsigned char>& image, const QImagePreTreatParams & params)
{
// 获取数据中的最大灰度值,并统计灰度直方图
memset(m_arrayBuffer2.buffer(), 0x00, 256 * sizeof(int));
for (int i = 0; i < image.size(); i++)
{
m_arrayBuffer2(image(i))++;
}
int beginAmount = image.size() * params.gradataionCutBegin() / 1000;
int endAmount = image.size() * params.gradationCutEnd() / 1000;
unsigned char beginThreshold = 0;
unsigned char endThreshold = 255;
// 按比例获取最暗的部分的阈值
int sum = 0;
for (int i = 0; i < 256; i++)
{
sum += m_arrayBuffer2(i);
if (sum > beginAmount)
{
beginThreshold = i;
break;
}
}
// 按比例获取最亮的部分的阈值
sum = 0;
for (int i = 255; i >= 0; i--)
{
sum += m_arrayBuffer2(i);
if (sum > endAmount)
{
endThreshold = i;
break;
}
}
// 按阈值将图像重新映射到0~255范围内
if (beginThreshold != endThreshold)
{
for (int i = 0; i < image.size(); i++)
{
if (image(i) <= beginThreshold)
{
image(i) = 0;
}
else if (image(i) >= endThreshold)
{
image(i) = 255;
}
else
{
image(i) = 255 * (image(i) - beginThreshold) / (endThreshold - beginThreshold);
}
}
}
else
{
for (int i = 0; i < image.size(); i++)
{
image(i) = endThreshold;
}
}
}
9.伪彩图
opencv提供了12种伪彩色COLORMAP_*
applyColorMap
:COLORMAP_BONE, COLORMAP_JET, COLORMAP_RAINBOW, COLORMAP_SUMEER...
matlab中提供了colormap伪彩图18种
colormap
:jet, hsv, hot...
C++实现jet
void setColor(QImage& image, unsigned char max, unsigned char min)
{
const int size = 42;
double posSlope = (max - min) / size;
double negSlope = (min - max) / size;
for (int i = 0; i < 256; ++i)
{
QRgb rgb = 0xFF000000;
if (i < size)
{
unsigned char g = static_cast<unsigned char>(round(posSlope * i + min)) ;
rgb += static_cast<QRgb>((max << 16) + (g << 8) + min);
}
else if (i < size *2)
{
unsigned char r = static_cast<unsigned char>(round(negSlope*i + 2 * max + min));
rgb += static_cast<QRgb>((r << 16) + max << 8 + min);
}
else if (i < size*3)
{
unsigned char b = static_cast<unsigned char>(round(posSlope*i - 2 * max + min));
rgb += static_cast<QRgb>(min << 16 + max << 8 + b);
}
else if (i < size*4)
{
unsigned char g = static_cast<unsigned char>(round(negSlope * i + 4*max + min));
rgb += static_cast<QRgb>((max << 16) + (g << 8) + min);
}
else if (i < size *5)
{
unsigned char r = static_cast<unsigned char>(round(posSlope*i - 4 * max + min));
rgb += static_cast<QRgb>((r << 16) + max << 8 + min);
}
else
{
unsigned char b = static_cast<unsigned char>(round(negSlope*i + 6 * max));
rgb += static_cast<QRgb>(min << 16 + max << 8 + b);
}
image.setColor(i, rgb);
}
}
10. linux(QtCreator)与window(VS2015)注意事项
- include引用时,QtCreator下路径使用“/”,框架路径放在前列(方便排错),区分大小写;
- 注意
__super
之类(vc ++扩展)的使用,完全可以用基类类型名替代; - 文件格式编码,最好统一成UTF-8格式,否则会出现奇怪的乱码;
- 图片格式错误:
libpng warning: iCCP: know incorrect sRGB profile
处理方法(修改格式):from PyQt5.QtGui import * import os img = QImage() path = "./img" for root , dirs, files in os.walk(path): for name in files: print(name) if name.endswith(".png"): print(name) print("./img/"+ name) img.load("./img/"+name) img.save("./img/"+name)
11. QUuid去括号
在5.11版本前,使用Quuid::createUuid().toString().remove("{").remove("}")
;
之后可以使用Quuid::createUuid().toString(QUuid::WithBraces)
;
12.QApplication
参数传值方式应该为引用,否则会报内存出错std::bad_alloc
参数列表应该为(int &argc, char **argv)