在python中创建可单击的网格

2024-09-29 02:19:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我是python新手,需要一些帮助来启动我的应用程序。我想为我的硕士论文写一个免费的开源应用程序,目的是解决静态结构

到目前为止,我有两个主要的python库:PyQt5(用于用户界面)和matplotlib(用于在解决结构后显示一些有用的图表)

我需要一些功能,让用户“画”出他们想要分析的结构。我曾想过(并尝试过)使用matplotlib作为这个“抽屉”,但我认为我不应该遵循这条路径,因为这不是库设计的目的。我将在下面解释所需的功能

静态结构是通过“节点”和“条”定义的。我的设想是,当开始一个项目时,会出现一个带有可测量网格的画布。在这里,单击一个按钮,用户可以在画布中单击,以创建一个“节点”,该节点可以用圆或其他形式表示。此节点将保留在原来的位置,直到用户决定删除它

我附上一份image,目的是澄清解释

有没有提供此功能的软件包?或者有人知道如何实现这个功能吗


Tags: 用户目的功能应用程序节点matplotlib画布图表
1条回答
网友
1楼 · 发布于 2024-09-29 02:19:53

我尝试了一下,因为我很好奇要把matplotlib变成一个简单的绘图工具需要付出多大的努力

下面是一个工作(纯matplotlib!)示例,您应该能够将其作为开始点来做您想做的事情

import matplotlib.pyplot as plt

f = plt.figure(figsize=(8, 8))
ax = f.add_subplot()

# initialize your grid
ax.set_xlim(0, 10)
ax.set_ylim(0, 10)
ax.xaxis.set_major_locator(plt.FixedLocator(range(10)))
ax.yaxis.set_major_locator(plt.FixedLocator(range(10)))
ax.grid()


# print some info text
t1 = ax.text(.5, .5,
"""LEFT-click to draw a line
RIGHT-click to remove the last point
MIDDLE-click to toggle 'snap-to-grid'""",
bbox=dict(facecolor='w',
          edgecolor='black',
          boxstyle='round, pad=1, rounding_size=1', pad=0))

t2 = ax.text(7, .5,
"""'snap-to-grid active!'""",
bbox=dict(facecolor='w',
          edgecolor='red',
          boxstyle='round, pad=1, rounding_size=1', pad=0))
t2.set_visible(False)


# draw initial lines that will be updated later
l, = ax.plot([], [], lw=2, marker='o', c='k')
p, = ax.plot([], [], lw=0, marker='.', c='r', alpha=0.25)
p_round, = ax.plot([], [], lw=0, marker='o', c='r')


# get a dict to store the values you need to change during runtime
retdict = dict(points=[],
               round_to_int=False)

# define what to do when a mouse-click event is happening
def on_click(event):
    if event.inaxes != ax:
        return
    if event.button == 1:  # (e.g. left-click)
        if retdict['round_to_int']:
            retdict['points'] += [[round(event.xdata), round(event.ydata)]]
        else:
            retdict['points'] += [[event.xdata, event.ydata]]
    elif event.button == 3:  # (e.g. right-click)
        if len(retdict['points']) >= 1:
            retdict['points'] = retdict['points'][:-1]
            plt.draw()

    elif event.button == 2:  # (e.g. middle-click)
        retdict['round_to_int'] = not retdict['round_to_int']
        if retdict['round_to_int']:
            t2.set_visible(True)
        else:
            t2.set_visible(False)
        plt.draw()

    if len(retdict['points']) > 0:
        l.set_visible(True)
        l.set_data(list(zip(*retdict['points'])))

        plt.draw()
    else:
        l.set_visible(False)


# define what to do when a motion-event is detected
def on_move(event):
    if event.inaxes != ax:
        return

    p.set_data(event.xdata, event.ydata)

    if retdict['round_to_int']:
        p_round.set_data(round(event.xdata), round(event.ydata))

    plt.draw()

# connect the callbacks to the figure
f.canvas.mpl_connect('button_press_event', on_click)
f.canvas.mpl_connect('motion_notify_event', on_move)

相关问题 更多 >