这里写自定义目录标题
QT绘制PRPD
在Qt上先将图谱绘制到位图中,然后再将位图绘制到QWidget上,这样外部窗口变换大小都不会影响到图谱的准确性。
m_Bitmap->fill(Qt::transparent);//用透明色填充
QPainter m_MemDC(m_Bitmap);
QPainter* m_MemDCBK=pDC;
QRect rectBK = rect;
m_MemDCBK->fillRect(rectBK,QColor(0,0,0));
m_MemDCBK->setPen(QColor(255,255,255));
QRect rectFP = QRect(0,0,FP_X,FP_Y);
m_MemDC.fillRect(rectFP,m_colorBK);
QPen GrayPen(m_colorBKLine,0,Qt::SolidLine);
m_MemDC.setPen(GrayPen);
m_MemDC.drawLine(rectFP.left(),rectFP.top()+rectFP.height()/2,rectFP.right(),rectFP.top()+rectFP.height()/2);
int nOldY = rectFP.top()+rectFP.height()/2;
int nY = rectFP.top()+rectFP.height()/2;
for(int k=rectFP.left();k<rectFP.right();k++)//画背景正弦曲线
{
nY = rectFP.top()+rectFP.height()/2-sin((double)(k-rectFP.left())/(double)(rectFP.width()/2)*PI)*(rectFP.top()+rectFP.height()/2);
m_MemDC.drawLine(k-1,nOldY,k,nY);
nOldY=nY;
}
int nTypeValue ;
if(g_nFPType == 0)
{
nTypeValue = FP_Y/2;
}
else if(g_nFPType == 1)
{
nTypeValue = FP_Y;
}
for(int i=0;i<FP_X;i++)
{
int move_num=i-g_nRotate[chan_idx_]*FP_X/360;
if(move_num<=0)
{
move_num=move_num+FP_X;
}
int phase_move_num; //定义旋转多少相位
phase_move_num=move_num%FP_X;
for(int j=0;j<FP_Y;j++)
{
if(abs(j-nTypeValue)>m_nBK)
{
if(m_colorBK!=GetFPColor(m_sStateMap[i][j]))
{
m_MemDC.setPen(GetFPColor(m_sStateMap[i][j]));
m_MemDC.drawPoint(QPointF(i,j));
}
}
}
}
m_MemDCBK->setFont(QFont("Times",8,QFont::Black));
m_MemDCBK->drawPixmap(30,0,rect.width()-30,rect.height()-20,*m_Bitmap,0,0,FP_X,FP_Y);
m_MemDC.end();
m_MemDCBK->end();
图谱转为vs+DUILIB绘制
刚将代码放到duilib框架中时,想的是直接绘制出来
void xxx::PaintBkImage(HDC hDC)
{
int32_t left = m_rcItem.left;
int32_t right = m_rcItem.right - 1;
int32_t top = m_rcItem.top;
int32_t bottom = m_rcItem.bottom - 1;
int32_t width = right - left;
int32_t height = bottom - top;
RECT rc_line = { 0 };
rc_line.left = 0;
rc_line.top = height / 2;
rc_line.right = width;
rc_line.bottom = height / 2;
CRenderEngine::DrawLine(memdc, rc_line, 2, m_colorBKLine);
int nOldY = height / 2;
int nY = height / 2;
for (int k = 0; k<width; k++)//画背景正弦曲线
{
nY = top + height / 2 - sin((double)(k - left) / (double)(width/ 2)*PI)*(top + height / 2);
rc_line.left = k - 1;
rc_line.top = nOldY;
rc_line.right = k;
rc_line.bottom = nY;
CRenderEngine::DrawLine(memdc, rc_line, 3, m_colorBKLine);
nOldY = nY;
}
PaintWaves(hDC);
}
void xxx::PaintWaves(HDC hDC)
{
int nTypeValue;
if (g_nFPType == 0)
{
nTypeValue = FP_Y / 2;
}
else if (g_nFPType == 1)
{
nTypeValue = FP_Y;
}
for (int i = 0; i<FP_X; i++)
{
int move_num=i-g_nRotate[chan_idx_]*FP_X/360;
if(move_num<=0)
{
move_num=move_num+FP_X;
}
int phase_move_num; //定义旋转多少相位
phase_move_num=move_num%FP_X;
for (int j = 0; j<FP_Y; j++)
{
if (abs(j - nTypeValue)>m_nBK)
{
if (m_colorBK != GetFPColor(m_sStateMap[i][j]))
{
HPEN pen = CreatePen(PS_SOLID, 2, GetFPColor(m_sStateMap[i][j]));
HGDIOBJ old_pen = SelectObject(hDC, pen);
Ellipse(hDC, i, j, i + 1, j + 1);
SelectObject(hDC, old_pen);
DeletePen(pen);
}
}
}
}
}
这样就遇到了一个很严重的问题,背景正弦曲线虽然会跟着窗口大小变动而变动,但图谱的数据却重新分布重新绘制了。所以还是得使用位图来绘制。
void xxx::PaintBkImage(HDC hDC)
{
HDC memdc = CreateCompatibleDC(hDC);
HBITMAP hbmp = CreateCompatibleBitmap(hDC, FP_X, FP_Y);
HBITMAP holdbmp = (HBITMAP)SelectObject(memdc, hbmp);
rc_line.left = 0;
rc_line.top = FP_Y / 2;
rc_line.right = FP_X;
rc_line.bottom = FP_Y / 2;
CRenderEngine::DrawLine(memdc, rc_line, 2, m_colorBKLine);
int nOldY = FP_Y / 2;
int nY = FP_Y / 2;
for (int k = 0; k<FP_X; k++)//画背景正弦曲线
{
nY = FP_Y / 2 - sin((double)(k - left) / (double)(FP_X / 2)*PI)*(FP_Y / 2);
rc_line.left = k - 1;
rc_line.top = nOldY;
rc_line.right = k;
rc_line.bottom = nY;
CRenderEngine::DrawLine(memdc, rc_line, 3, m_colorBKLine);
nOldY = nY;
}
PaintWaves(hDC, memdc);
StretchBlt(hDC, left, top, width, height, memdc, 0, 0, FP_X, FP_Y, SRCCOPY);
SelectObject(memdc, holdbmp);
DeleteDC(memdc);
}
void xxx::PaintWaves(HDC hDC, HDC memdc)
{
int nTypeValue;
if (g_nFPType == 0)
{
nTypeValue = FP_Y / 2;
}
else if (g_nFPType == 1)
{
nTypeValue = FP_Y;
}
for (int i = 0; i<FP_X; i++)
{
int move_num=i-g_nRotate[chan_idx_]*FP_X/360;
if(move_num<=0)
{
move_num=move_num+FP_X;
}
int phase_move_num; //定义旋转多少相位
phase_move_num=move_num%FP_X;
for (int j = 0; j<FP_Y; j++)
{
if (abs(j - nTypeValue)>m_nBK)
{
if (m_colorBK != GetFPColor(m_sStateMap[i][j]))
{
HPEN pen = CreatePen(PS_SOLID, 2, GetFPColor(m_sStateMap[i][j]));
HGDIOBJ old_pen = SelectObject(memdc, pen);
Ellipse(memdc, i, j, i + 1, j + 1);
SelectObject(memdc, old_pen);
DeletePen(pen);
}
}
}
}
}
总结
Qt画点使用drawPoint,用dui画点要用Ellipse,且right - left = bottom - top。
创建新的HBITMAP要使用CreateCompatibleBitmap而不能用CreateBitmap,原因是CreateBitmap似乎只支持8x8的位图。
画笔、画刷、画布、位图的句柄用完之后一定要释放。