You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySimpleGUI双旋钮滑块开发:如何获取绘制圆的中心位置?

问题描述

想要用PySimpleGUI创建带双旋钮的滑块,但原生Slider元素不支持双旋钮,于是基于官方Demo修改代码,用Graph元素绘制两个可拖动的圆作为旋钮,现在需要直接获取绘制的圆的中心位置,而非鼠标位置。

解决方案

PySimpleGUI的Graph元素没有直接提供获取图形当前位置的API,因此需要手动维护每个旋钮的坐标。具体实现如下:

  • 初始化时记录每个旋钮的初始中心坐标
  • 拖动旋钮时,根据移动的偏移量更新对应旋钮的坐标
  • 需要获取位置时直接从维护的坐标数据中读取

修改后的完整代码:

import PySimpleGUI as sg

layout = [[sg.Graph(
            canvas_size=(400, 20),
            graph_bottom_left=(0, 0),
            graph_top_right=(800, 40),
            key="-GRAPH-",
            enable_events=True,
            drag_submits=True,
            motion_events=True,
            right_click_menu=[[''],['Erase item','Send to back']]
            )],
        [sg.Text(key='-INFO-', size=(60, 1))]]

window = sg.Window("双旋钮滑块", layout, finalize=True)

graph = window["-GRAPH-"]
# 绘制旋钮并记录初始位置
knob1 = graph.draw_circle((20, 20), 20, fill_color='red')
knob2 = graph.draw_circle((50, 20), 20, fill_color='blue')
# 用字典维护每个旋钮的当前中心坐标
knob_positions = {
    knob1: (20, 20),
    knob2: (50, 20)
}

dragging = False
current_drag_knob = None
last_x = 0

while True:
    event, values = window.read()
    if event == sg.WIN_CLOSED:
        break
    if event == "-GRAPH-":
        x, y = values["-GRAPH-"]
        if not dragging:
            # 检测点击的目标旋钮
            drag_figures = graph.get_figures_at_location((x, y))
            if drag_figures:
                current_drag_knob = drag_figures[0]
                dragging = True
                last_x = x
        else:
            if current_drag_knob:
                delta_x = x - last_x
                last_x = x
                # 获取旋钮当前坐标
                curr_x, curr_y = knob_positions[current_drag_knob]
                # 限制旋钮在Graph范围内移动
                new_x = max(0, min(800, curr_x + delta_x))
                # 可选:确保两个旋钮不重叠,保留间距
                other_knob = knob2 if current_drag_knob == knob1 else knob1
                other_x = knob_positions[other_knob][0]
                if current_drag_knob == knob1:
                    new_x = min(new_x, other_x - 10)
                else:
                    new_x = max(new_x, other_x + 10)
                # 计算实际移动偏移量并移动图形
                actual_delta = new_x - curr_x
                graph.move_figure(current_drag_knob, actual_delta, 0)
                # 更新坐标记录
                knob_positions[current_drag_knob] = (new_x, curr_y)
                # 显示当前旋钮中心位置
                knob_name = "红色旋钮" if current_drag_knob == knob1 else "蓝色旋钮"
                window["-INFO-"].update(
                    value=f"{knob_name}中心: ({new_x:.0f}, {curr_y:.0f}) | 鼠标位置: ({x}, {y})"
                )
    elif event.endswith('+UP'):
        dragging = False
        current_drag_knob = None

window.close()
关键说明
  • 用knob_positions字典存储每个旋钮的中心坐标,初始化时设置初始值
  • 拖动开始时通过get_figures_at_location确定当前拖动的旋钮
  • 移动旋钮时,先计算符合边界规则的新坐标,再同步更新字典中的记录
  • 需要获取位置时,直接从knob_positions中读取即可,完全独立于鼠标位置

内容的提问来源于stack exchange,提问作者Andythe_great

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 17:33:10