Qt版本在此:Qt编写自定义控件:时间选择控件_qt如何写一个按钮时间-CSDN博客
代码:
bool pressed;
int hour{0};
int minute{0};
bool isEditHour{false};
lv_area_t txt_coords;
static void event_cb000(lv_event_t * e)
{
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t * obj = lv_event_get_target(e);
if(code == LV_EVENT_REFR_EXT_DRAW_SIZE)
{
lv_coord_t * s = (lv_coord_t *)lv_event_get_param(e);
*s = LV_MAX(*s, 20);
}
else if(code == LV_EVENT_DRAW_POST_END)
{
lv_draw_rect_dsc_t rect_dsc;
lv_draw_rect_dsc_init(&rect_dsc);
lv_obj_init_draw_rect_dsc(obj, LV_PART_MAIN, &rect_dsc);
rect_dsc.bg_color = lv_color_hex(0xe0e0e0);
rect_dsc.bg_grad_color = lv_color_hex(0x1c1c1c);
rect_dsc.bg_grad_dir = LV_GRAD_DIR_HOR;
const lv_area_t * clip_area = (const lv_area_t *)lv_event_get_param(e);
lv_area_t area = obj->coords;
lv_draw_arc_dsc_t arc_dsc;
lv_draw_arc_dsc_init(&arc_dsc); // 使用默认设置初始化
lv_obj_init_draw_arc_dsc(obj,LV_PART_MAIN,&arc_dsc);
arc_dsc.color = lv_color_hex(0x00FF00); // 设置线条颜色为红色
arc_dsc.width = 3;
// 计算圆心位置(这里以Canvas中心为例)
lv_coord_t x = (area.x2 - area.x1) / 2 + area.x1;
lv_coord_t y = (area.y2 - area.y1) / 2 + area.y1;
lv_coord_t r = (area.x2 - area.x1) / 2;
lv_draw_arc(x,y,r,0,360,clip_area,&arc_dsc);
int side = LV_MIN(area.x2 - area.x1, area.y2 - area.y1) * 0.36;
int drawAngle;
if(isEditHour)
{
drawAngle = hour * 15;
}
else
{
drawAngle = minute * 6;
}
lv_point_t centerPos = lv_point_t{x,y};
lv_draw_line_dsc_t line_dsc;
lv_draw_line_dsc_init(&line_dsc); // 初始化绘图描述符
lv_obj_init_draw_line_dsc(obj, LV_PART_MAIN, &line_dsc);
line_dsc.color = lv_color_hex(0xFF0000); // 设置线条颜色
line_dsc.width = 2; // 设置线条宽度
int A = 90 - drawAngle;
double angle_rad_A = A * M_PI / 180.0; // 将角度转换为弧度
lv_point_t endPos;
endPos.x = centerPos.x + cos(angle_rad_A) * side;
endPos.y = centerPos.y - sin(angle_rad_A) * side;
// lv_draw_line(¢erPos, &endPos, clip_area, &line_dsc);
lv_draw_arc(endPos.x,endPos.y,side * 0.25,0,360,clip_area,&arc_dsc);
std::string time24 = std::to_string(hour) + " : " + std::to_string(minute);
lv_point_t txt_size;
lv_txt_get_size(&txt_size, time24.c_str(),
lv_obj_get_style_text_font(obj, LV_PART_MAIN),
lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN),
0,
LV_COORD_MAX, LV_TEXT_FLAG_NONE);
txt_coords.x1 = area.x1 + (area.x2 - area.x1 - txt_size.x) / 2;
txt_coords.y1 = area.y1 + (area.y2 - area.y1 - txt_size.y) / 2;
txt_coords.x2 = txt_coords.x1 + txt_size.x;
txt_coords.y2 = txt_coords.y1 + txt_size.y;
lv_draw_label_dsc_t label_dsc;
lv_draw_label_dsc_init(&label_dsc);
lv_obj_init_draw_label_dsc(obj, LV_PART_MAIN, &label_dsc);
lv_draw_label(&txt_coords, clip_area, &label_dsc, time24.c_str(), NULL);
}
else if(code == LV_EVENT_PRESSED)
{
lv_point_t point;
lv_indev_get_point(lv_event_get_indev(e), &point); // 获取当前输入设备的点坐标
if(_lv_area_is_point_on(&txt_coords,&point,0))
{
isEditHour = !isEditHour;
lv_obj_set_style_text_color(obj,lv_color_hex(isEditHour ? 0x128bf1 : 0xff2222),LV_PART_MAIN);
}
else
{
pressed = true;
}
lv_obj_invalidate(obj);
}
else if(code == LV_EVENT_RELEASED)
{
pressed = false;
lv_obj_invalidate(obj);
}
else if(code == LV_EVENT_PRESSING)
{
if(pressed)
{
lv_point_t point;
lv_indev_get_point(lv_event_get_indev(e), &point); // 获取当前输入设备的点坐标
lv_area_t area = obj->coords;
lv_coord_t x = (area.x2 - area.x1) / 2 + area.x1;
lv_coord_t y = (area.y2 - area.y1) / 2 + area.y1;
lv_point_t centerPos = lv_point_t{x,y};
{
double angle = atan2(point.y-centerPos.y,point.x-centerPos.x); //两点之间的角度(弧度)
angle = -angle*(180 / 3.1415926); //0°~180° - -180°~0°
angle -= 90;
if(angle < 0.0)
{
angle = 360.0 - abs(angle);
}
angle = (360 - angle);
if(isEditHour)
{
hour = angle / 15;
}
else
{
minute = angle / 6;
}
}
lv_obj_invalidate(obj);
}
}
}
int main(int argc, char **argv)
{
lv_init();
hal_init();
lv_log_register_print_cb(esp32_log_cb);
{
lv_obj_t * obj = lv_obj_create(lv_scr_act());
lv_obj_set_size(obj, 200, 200);
lv_obj_center(obj);
auto style = new lv_style_t;
lv_style_init(style);
lv_style_set_bg_color(style,lv_color_hex(0xffffff));
lv_style_set_radius(style, LV_RADIUS_CIRCLE);
lv_style_set_border_color(style,lv_color_hex(0x00dd66));
lv_style_set_border_width(style,0);
lv_style_set_text_color(style,lv_color_hex(0x128bf1));
lv_obj_add_style(obj, style, LV_PART_MAIN);
lv_obj_add_event_cb(obj, event_cb000,LV_EVENT_ALL,0);
}
while (1)
{
lv_timer_handler();
usleep(5 * 1000);
}
return 0;
}
效果: