GDI+学习系列:
Qt中使用GDI+绘图
GDI+中的基础类总结
GDI+中基本图形绘制
背景
图形类 Graphics 是 GDI+的核心,它提供绘制图形、图像和文本的各种方法。Graphics 中使用 DrawString 方法在指定位置绘制文本或者在一个指定矩形内绘制文本。
文本格式化
①.概述
StringFormat 用于设置绘制字符串时的各种格式,其中关键参数是格式标志位StringFormatFlags。
②.StringFormatFlags
formatFlags是一系列枚举值的位或。
typedef enum {
// 设置靠右对齐,(缺省为左对齐)
StringFormatFlagsDirectionRightToLeft = 0x00000001,
// 设置垂直方向输出,(缺省为水平方向)
StringFormatFlagsDirectionVertical = 0x00000002,
// 允许字符尾部悬于矩形之外
StringFormatFlagsNoFitBlackBox = 0x00000004,
// Unicode 布局控制符起作用
StringFormatFlagsDisplayFormatControl = 0x00000020,
// 有替换用的“缺少字体”(缺省为开方形符)
StringFormatFlagsNoFontFallback = 0x00000400,
// 测量时包含尾部空格符(缺省不包含)
StringFormatFlagsMeasureTrailingSpaces = 0x00000800,
// 不自动换行 缺省自动换行)
StringFormatFlagsNoWrap = 0x00001000,
// 最后一行必须为整行高,避免半行高的输出
StringFormatFlagsLineLimit = 0x00002000,
// 不使用剪裁(缺省不剪裁,可以显示半行)
StringFormatFlagsNoClip = 0x00004000
} StringFormatFlags;
设置文本输出方向
缺省的文本串输出方向是从左到右水平绘制。也可以在 StringFormat 类的构造函数中 使 用 参 数 值 :StringFormatFlagsDirectionRightToLeft 和 StringFormatFlagsDirectionVertical 来修改文本串的输出方向为从右到左水平绘制和从 上到下垂直绘制。
void DemoGDI::DrawUser(HDC hdc)
{
Graphics graphics(hdc);//构造 Graphics 对象
Font font(L"宋体", 12, FontStyleRegular, UnitPixel);
SolidBrush solidBrush(Color::Blue);
Pen m_pen(Color::Black);
//默认格式
{
RectF rectF(20.0f, 20.0f, 150.0f, 40.0f);
graphics.DrawRectangle(&m_pen, rectF);
StringFormat stringFormat;
graphics.DrawString(L"靠左水平输出", -1, &font, rectF, &stringFormat, &solidBrush);
}
//靠右对齐
{
RectF rectF(20.0f, 65.0f, 150.0f, 40.0f);
graphics.DrawRectangle(&m_pen, rectF);
StringFormat stringFormat(StringFormatFlagsDirectionRightToLeft);
graphics.DrawString(L"靠右水平输出", -1, &font, rectF, &stringFormat, &solidBrush);
}
//靠右对齐垂直输出
{
RectF rectF(20.0f, 110.0f, 150.0f, 40.0f);
graphics.DrawRectangle(&m_pen, rectF);
StringFormat stringFormat(StringFormatFlagsDirectionRightToLeft| StringFormatFlagsDirectionVertical);
graphics.DrawString(L"靠右垂直输出", -1, &font, rectF, &stringFormat, &solidBrush);
}
}
文本裁剪和换行
缺省情况下,使用矩形输出长文本串时,会自动换行和剪裁。但是也可以在 StringFormatF 类的构造函数中,利用第一个输入参数的 StringFormatFlags 枚举值,来改变默认的设置。
void DemoGDI::DrawUser(HDC hdc)
{
Graphics graphics(hdc);//构造 Graphics 对象
Font font(L"宋体", 12, FontStyleRegular, UnitPixel);
SolidBrush solidBrush(Color::Blue);
Pen m_pen(Color::Black);
//默认格式
{
RectF rectF(20.0f, 20.0f, 60.0f, 20.0f);
graphics.DrawRectangle(&m_pen, rectF);
StringFormat stringFormat;
graphics.DrawString(L"GDI+绘制文本", -1, &font, rectF, &stringFormat, &solidBrush);
}
//取消自动换行
{
RectF rectF(20.0f, 50.0f, 60.0f, 20.0f);
graphics.DrawRectangle(&m_pen, rectF);
StringFormat stringFormat(StringFormatFlagsNoWrap);
graphics.DrawString(L"GDI+绘制文本", -1, &font, rectF, &stringFormat, &solidBrush);
}
//取消裁剪
{
RectF rectF(20.0f, 80.0f, 60.0f, 20.0f);
graphics.DrawRectangle(&m_pen, rectF);
StringFormat stringFormat(StringFormatFlagsNoClip);
graphics.DrawString(L"GDI+绘制文本", -1, &font, rectF, &stringFormat, &solidBrush);
}
//进行行限制
{
RectF rectF(20.0f, 110.0f, 60.0f, 20.0f);
graphics.DrawRectangle(&m_pen, rectF);
StringFormat stringFormat(StringFormatFlagsLineLimit);
graphics.DrawString(L"GDI+绘制文本", -1, &font, rectF, &stringFormat, &solidBrush);
}
}
对齐设置
可以通过 StringFormat 类的成员函数来设置输出文本串的对齐方式:SetAlignment 每行文本的水平方向对齐。SetLineAlignment 设置文本块整体的垂直方向对齐。
void DemoGDI::DrawUser(HDC hdc)
{
Graphics graphics(hdc);//构造 Graphics 对象
Font font(L"宋体", 12, FontStyleRegular, UnitPixel);
SolidBrush solidBrush(Color::Blue);
Pen m_pen(Color::Black);
//水平、垂直居中
{
RectF rectF(20.0f,30.0f, 160.0f, 50.0f);
graphics.DrawRectangle(&m_pen, rectF);
StringFormat stringFormat(StringFormatFlagsNoWrap);
stringFormat.SetAlignment(StringAlignmentCenter);
stringFormat.SetLineAlignment(StringAlignmentCenter);
graphics.DrawString(L"GDI+绘制文本", -1, &font, rectF, &stringFormat, &solidBrush);
}
}
设置制表位
通过调用 StringFormat 对象的 SetTabStops 方法,可以设置文本的制表位。
void DemoGDI::DrawUser(HDC hdc)
{
Graphics graphics(hdc);//构造 Graphics 对象
Font font(L"宋体", 16, FontStyleRegular, UnitPixel);
SolidBrush solidBrush(Color::Blue);
Pen m_pen(Color::Black);
QString m_text = "姓名\t语文\t数学\r\n"
"张三\t80\t90\r\n"
"李四\t100\t60";
RectF rectF(20.0f, 30.0f, 250.0f, 100.0f);
graphics.DrawRectangle(&m_pen, rectF);
float tabs[] = { 60.0f, 100.0f};
StringFormat stringFormat;
stringFormat.SetTabStops(0.0f, 2, tabs);
graphics.DrawString(m_text.toStdWString().c_str(), -1, &font, rectF, &stringFormat, &solidBrush);
}
字符串去尾
当字符串在指定的区域区域无法完整显示时,需要指定怎么对文本进行截取。通过调用StringFormat 对象的 SetTrimming 方法可以对文本进行去尾设置。
void DemoGDI::DrawUser(HDC hdc)
{
Graphics graphics(hdc);//构造 Graphics 对象
SolidBrush solidBrush(Color::Blue);
Font font(L"宋体", 24, FontStyleRegular, UnitPixel);
QString m_txt = "在Qt中使用GDI+示例";
//默认格式
{
RectF rectF(20.0f, 30.0f, 100.0f, 60.0f);
StringFormat stringFormat;
graphics.DrawString(m_txt.toStdWString().c_str(), -1, &font, rectF, &stringFormat, &solidBrush);
}
//按单词去尾,并用...代替
{
RectF rectF(20.0f, 100.0f, 100.0f, 60.0f);
StringFormat stringFormat;
stringFormat.SetTrimming(StringTrimmingEllipsisWord);
graphics.DrawString(m_txt.toStdWString().c_str(), -1, &font, rectF, &stringFormat, &solidBrush);
}
//按字符去尾,并用...代替
{
RectF rectF(20.0f, 170.0f, 100.0f, 60.0f);
StringFormat stringFormat;
stringFormat.SetTrimming(StringTrimmingEllipsisCharacter);
graphics.DrawString(m_txt.toStdWString().c_str(), -1, &font, rectF, &stringFormat, &solidBrush);
}
//显示首尾,并用...代替
{
RectF rectF(20.0f, 240.0f, 100.0f, 60.0f);
StringFormat stringFormat;
stringFormat.SetTrimming(StringTrimmingEllipsisPath);
graphics.DrawString(m_txt.toStdWString().c_str(), -1, &font, rectF, &stringFormat, &solidBrush);
}
}
平滑处理
文字在被放大后出现明显的锯齿现象, 为了提高文字的清晰度,需要对绘制的文本串进行平滑处理。通过调用 Graphics 对象的 SetTextRenderingHint 来设置文本质量。
graphics.SetTextRenderingHint(TextRenderingHintClearTypeGridFit);