I have this project, and I want to make it draw chemical structures (for example, water molecule) into a canvas, I have the list elements, contains the elements, I can't find a way to make an algorithm to draw the elements correctly, for example, if i feed into it two hydrogen atoms and one oxygen atom, it should draw the water molecule. it's not that simple, the hydrocarbons are such hard to draw structures. thanks in Advance!
here is my code:
import customtkinter
from CTkTable import *
import json
config_dir = "config.json"
with open(config_dir, 'r') as file:
data = json.load(file)
elements = [["H", "Hydrogen", 2, 1], ["O", "Oxygen", 1, 2]]
Font = (data["Font"], int(data["Font-Size"]), data["Font-Weight"])
print(Font)
def draw_molecule(canvas, sorted_bonds, bonds_location):
canvas.delete("all")
shift = int(data["Shift"])
def draw(x, y, text):
canvas.create_text((x, y), text=text, font=Font, fill=data["Color"])
canvas.update()
for i, (element_symbol, count, element_name) in enumerate(sorted_bonds):
x, y = bonds_location[i]
# Adjust x and y based on shift
x += shift * i
y += shift * i
for j in range(count):
draw(x, y, element_symbol)
y += shift # Move to the next vertical position
x += shift # Move to the next horizontal position
canvas.update()
def change_appearance_mode_event(new_appearance_mode: str):
customtkinter.set_appearance_mode(new_appearance_mode)
def change_color_theme_event(new_color_theme: str):
customtkinter.set_default_color_theme(new_color_theme)
def motion(event):
x, y = event.x, event.y
position_label.configure(text=f"Position: {x}, {y}")
position_label.pack(side="bottom")
def edit_win():
win = customtkinter.CTk()
win.geometry("300x400")
win.title("Add Molecule")
win.resizable(False, False)
frame = customtkinter.CTkFrame(master=win)
frame.pack(pady=10, padx=10, fill="both", expand=True)
mole_type_frame = customtkinter.CTkFrame(master=frame, height=125)
mole_type_frame.pack(pady=10, padx=10, fill="both", side="top")
customtkinter.CTkLabel(mole_type_frame, text="Select Molecule Properties:").place(x=10, y=5)
elements_frame = customtkinter.CTkFrame(master=frame)
elements_frame.pack(pady=10, padx=10, fill="both", side="top")
win.mainloop()
appearance_mode = "dark"
color_theme = "dark-blue"
lines_color_theme = "#f2f2f2"
elements_color_theme = "white"
customtkinter.set_appearance_mode(appearance_mode)
customtkinter.set_default_color_theme(color_theme)
root = customtkinter.CTk()
root.geometry("920x520")
root.title("Chemo Auto")
tools_frame = customtkinter.CTkFrame(master=root, height=50)
tools_frame.pack(pady=5, padx=5, fill="both", expand=False, side="left")
preferences_frame = customtkinter.CTkFrame(master=tools_frame, height=125)
preferences_frame.pack(pady=5, padx=5, expand=False)
edit_frame = customtkinter.CTkFrame(master=tools_frame, height=115)
edit_frame.pack(pady=5, padx=5, expand=False)
customtkinter.CTkLabel(preferences_frame, text="Preferences").place(x=15, y=5)
customtkinter.CTkLabel(preferences_frame, text="Theme:").place(x=5, y=40)
theme_menu = customtkinter.CTkOptionMenu(preferences_frame, values=["System", "light", "dark"],
command=change_appearance_mode_event, width=100)
theme_menu.set(appearance_mode)
theme_menu.place(x=85, y=40)
customtkinter.CTkLabel(preferences_frame, text="Color Theme:").place(x=5, y=80)
color_theme_menu = customtkinter.CTkOptionMenu(preferences_frame, values=["blue", "dark-blue", "green"],
command=change_color_theme_event, width=100)
color_theme_menu.set(color_theme)
color_theme_menu.place(x=85, y=80)
customtkinter.CTkLabel(edit_frame, text="Edit Molecules").place(x=15, y=5)
customtkinter.CTkButton(edit_frame, text="Add Molecule", command=edit_win).place(x=25, y=35)
customtkinter.CTkButton(edit_frame, text="Delete Molecule", command=edit_win).place(x=25, y=70)
table_values = [["Mole #", "Name", "#"]]
sorted_bonds = []
bonds_location = [[50, 50], [100, 100], [150, 150], [200, 200]]
for i in range(len(elements)):
table_values.append([i + 1, elements[i][1], elements[i][2]])
for j in range(elements[i][2]):
sorted_bonds.append([elements[i][0], elements[i][3], elements[i][1]])
sorted_bonds.sort(key=lambda x: x[1], reverse=True)
print(sorted_bonds)
table = CTkTable(master=tools_frame, values=table_values, column=3, width=65, height=15)
table.pack()
struct_frame = customtkinter.CTkFrame(master=root)
struct_frame.pack(pady=5, padx=5, fill="both", expand=True, side="left")
canvas = customtkinter.CTkCanvas(struct_frame, bg="#2F2F2F", bd=0, highlightthickness=0, relief='ridge')
canvas.pack(fill="both", expand=True, padx=10, pady=10)
position_label = customtkinter.CTkLabel(canvas, text="Position: ", text_color="white")
canvas.bind("<Motion>", motion)
draw_molecule(canvas, sorted_bonds, bonds_location)
customtkinter.CTkLabel(tools_frame, text="Version: 1.0", text_color="#f2f2f2").pack(side="bottom")
root.mainloop()
I tried going for "for loops" but it didnt work, ive tried diverse methods, nothing seems to work.