开源控件:Qt/C++自定义异形窗口和颜色选择器 【工程源码联系博主索要】
使用 Qt 和 C++ 实现一个异形窗口和自定义颜色选择器的过程。
1. CustomShapeWidgetUi
类
该类实现了一个具有自定义形状和颜色选择功能的窗口。
构造函数 CustomShapeWidgetUi
CustomShapeWidgetUi::CustomShapeWidgetUi(const QString &imagePath, QDialog *parent)
: QDialog(parent), backgroundPixmap(imagePath), ui(new Ui::CustomShapeWidgetUi)
{
ui->setupUi(this);
// 设置窗口无边框,透明背景
setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
setAttribute(Qt::WA_TranslucentBackground);
// 设置窗口形状
setWindowShape(imagePath);
resize(backgroundPixmap.size()); // 调整窗口大小为图片大小
// 设置颜色选择器的响应
connect(ui->colorPicker, &CustomColorPicker::colorChanged, [=](QColor color) {
ui->colorEdit->setText(color.name());
});
// 设置关闭和确认按钮的功能
connect(ui->cancelButton, &QToolButton::clicked, this, &QDialog::reject);
connect(ui->okButton, &QToolButton::clicked, this, &QDialog::accept);
}
- 无边框和透明背景:
Qt::FramelessWindowHint
移除窗口边框,Qt::WA_TranslucentBackground
设置背景透明,配合异形窗口实现。 - 形状设置:调用
setWindowShape
,根据图片的非透明区域设置窗口形状。 - 颜色选择:
colorChanged
信号和槽函数更新colorEdit
显示颜色的十六进制值。 - 按钮功能:关闭按钮和确认按钮使用
reject
和accept
信号关闭对话框。
重写 paintEvent
void CustomShapeWidgetUi::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.drawPixmap(0, 0, backgroundPixmap);
QWidget::paintEvent(event); // 调用基类的 paintEvent 保持设计师元素的绘制
}
使用 QPainter
绘制背景图片,并调用基类的 paintEvent
保持其他 UI 元素的正常绘制。
setWindowShape
方法
void CustomShapeWidgetUi::setWindowShape(const QString &imagePath)
{
QPixmap pixmap(imagePath);
QRegion region;
// 根据图片的透明区域生成 QRegion
for (int y = 0; y < pixmap.height(); ++y) {
for (int x = 0; x < pixmap.width(); ++x) {
if (QColor(pixmap.toImage().pixel(x, y)).alpha() > 0) {
region += QRegion(x, y, 1, 1);
}
}
}
setMask(region);
}
这里通过遍历图片像素点,判断每个像素的透明度,以生成自定义窗口形状的 QRegion
,并将该 QRegion
应用到窗口的遮罩 (setMask
) 上。
2. CustomColorPicker
类
CustomColorPicker
类实现了一个自定义颜色选择器。
构造函数 CustomColorPicker
CustomColorPicker::CustomColorPicker(QWidget *parent)
: QWidget(parent), brightness(255), updatingBrightness(false)
{
setFixedSize(220, 220); // 设置控件大小
color = QColor::fromHsv(0, 255, brightness);
hueSatPoint = QPoint(0, height());
}
- 固定大小:颜色选择器被设置为 220x220。
- 初始颜色:默认颜色设置为最大亮度的红色,亮度设为 255。
- 位置初始化:
hueSatPoint
定位到左下角。
paintEvent
方法
void CustomColorPicker::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
// 绘制色相-饱和度选择区域
QImage hueSatImage(width() - 30, height(), QImage::Format_RGB32);
for (int x = 0; x < hueSatImage.width(); ++x) {
for (int y = 0; y < hueSatImage.height(); ++y) {
int hue = static_cast<int>((360.0 * x) / hueSatImage.width());
int saturation = static_cast<int>((255.0 * (hueSatImage.height() - y)) / hueSatImage.height());
QColor tempColor = QColor::fromHsv(hue, saturation, brightness);
hueSatImage.setPixelColor(x, y, tempColor);
}
}
painter.drawImage(0, 0, hueSatImage);
// 绘制亮度滑条
QLinearGradient gradient(0, 0, 0, height());
gradient.setColorAt(0, QColor::fromHsv(color.hue(), color.saturation(), 255));
gradient.setColorAt(1, QColor::fromHsv(color.hue(), color.saturation(), 0));
painter.fillRect(width() - 20, 0, 20, height(), gradient);
// 绘制选中点指示器
painter.setPen(QPen(Qt::black, 2));
painter.setBrush(Qt::NoBrush);
painter.drawRect(hueSatPoint.x() - 10, hueSatPoint.y() - 10, 20, 20);
// 绘制亮度滑条上的指示器
int brightnessY = height() - (brightness * height() / 255);
painter.drawRect(width() - 20, brightnessY - 5, 20, 10);
}
- 色相-饱和度区域:通过
QImage
绘制 2D 色相-饱和度区域,亮度保持不变。 - 亮度滑条:设置渐变颜色,用当前色相和饱和度生成亮度变化效果。
- 指示器:指示器在色相-饱和度区域和亮度滑条上,展示当前选中的颜色。
鼠标事件处理
void CustomColorPicker::mousePressEvent(QMouseEvent *event) {
if (event->x() < width() - 30) {
hueSatPoint = event->pos();
updatingBrightness = false;
updateColorFromHueSat();
} else {
updatingBrightness = true;
updateColorFromBrightness(event->y());
}
}
void CustomColorPicker::mouseMoveEvent(QMouseEvent *event) {
if (event->buttons() & Qt::LeftButton) {
if (updatingBrightness) {
updateColorFromBrightness(event->y());
} else if (event->x() < width() - 30) {
hueSatPoint = event->pos();
updateColorFromHueSat();
}
}
}
- 点击:判断点击的位置,是色相-饱和度区域还是亮度滑条。
- 拖动:在点击的区域内拖动时,更新相应的颜色。
更新颜色的方法
void CustomColorPicker::updateColorFromHueSat()
{
int hue = static_cast<int>((360.0 * hueSatPoint.x()) / (width() - 30));
int saturation = static_cast<int>((255.0 * (height() - hueSatPoint.y())) / height());
hue = qBound(0, hue, 359);
saturation = qBound(0, saturation, 255);
color.setHsv(hue, saturation, brightness);
emit colorChanged(color);
update();
}
void CustomColorPicker::updateColorFromBrightness(int y)
{
brightness = qBound(0, 255 * (height() - y) / height(), 255);
color.setHsv(color.hue(), color.saturation(), brightness);
emit colorChanged(color);
update();
}
- 色相和饱和度更新:根据
hueSatPoint
计算色相和饱和度,确保其在合理范围内 (qBound
)。 - 亮度更新:根据鼠标在亮度滑条上的位置更新亮度。
原文地址:https://blog.csdn.net/chenai886/article/details/143769389
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!