| |
---|
| | def __init__(self, master): |
---|
| | super().__init__(master) # スーパークラスのコンストラクタを実行 |
---|
| | self.master.title("Waypoints Manager") |
---|
| | |
---|
| | ## 画面上のメニューを作成 |
---|
| | ## 画面上部のメニューを作成 |
---|
| | self.menu_bar = tk.Menu(self) # メニューバーを配置 |
---|
| | self.file_menu = tk.Menu(self.menu_bar, tearoff=tk.OFF) # バーに追加するメニューを作成 |
---|
| | self.menu_bar.add_cascade(label="File", menu=self.file_menu) # Fileメニューとしてバーに追加 |
---|
| | self.file_menu.add_command(label="Save", command=self.menu_save_clicked, accelerator="Ctrl+S") # FileメニューにSaveコマンドを追加 |
---|
| | self.file_menu.add_command(label="Save As", command=self.menu_saveas_clicked, accelerator="Ctrl+Shift+S") # 同様にSave Asコマンドを追加 |
---|
| | self.bind_all("<Control-s>", self.menu_save_clicked) #キーボードショートカットを設定 |
---|
| | self.bind_all("<Control-Shift-S>", self.menu_saveas_clicked) |
---|
| | self.master.config(menu=self.menu_bar) # 大元に作成したメニューバーを設定 |
---|
| | self.update() # 情報を更新 |
---|
| | |
---|
| | ## map.pgm と map.yaml の読み込み |
---|
| | map_path = '..\..\waypoint_nav\maps\map' # .pgmと.yamlの手前までのパス |
---|
| | self.__map_img_pil = Image.open(Path(map_path+'.pgm')) # .pgmをplillowで読み込む オリジナル画像を保持するため再代入禁止 |
---|
| | with open(map_path+'.yaml') as file: # .yamlを読み込む |
---|
| | self.__map_yaml = ruamel.yaml.YAML().load(file) # こちらも再代入禁止 |
---|
| | ## map.pgm, map.yaml, waypoints.yaml の読み込み 3つの変数は再代入禁止 |
---|
| | self.__map_img_pil, self.__map_yaml = self.get_map_info() |
---|
| | self.__waypoints = self.get_waypoints() |
---|
| | |
---|
| | ## canvasを配置し画像を描画 |
---|
| | self.canvas = tk.Canvas(self.master, background="#008B8B") # 画像を描画するキャンバス |
---|
| | self.canvas.pack(expand=True, fill=tk.BOTH) # キャンバスを配置 |
---|
| | ## canvasを配置 |
---|
| | self.canvas = tk.Canvas(self.master, background="#008B8B") # 画像を描画するcanvas |
---|
| | self.canvas.pack(expand=True, fill=tk.BOTH) # canvasを配置 |
---|
| | self.update() # 情報の更新をする(canvasのサイズなどの情報が更新される) |
---|
| | |
---|
| | ## 画像をキャンバスのサイズにフィッティングして描画 |
---|
| | self.canv_w = self.canvas.winfo_width() # canvasの幅を取得 |
---|
| | self.canv_h = self.canvas.winfo_height() # canvasの高さを取得 |
---|
| | if (self.canv_w / self.canv_h) > (self.__map_img_pil.width / self.__map_img_pil.height): |
---|
| | # キャンバスの方が横長 画像をキャンバスの縦に合わせてリサイズ |
---|
| | scale = self.canv_h / self.__map_img_pil.height |
---|
| | ## 画像をcanvasのサイズにフィッティングして描画 |
---|
| | canv_w = self.canvas.winfo_width() # canvasの幅を取得 |
---|
| | canv_h = self.canvas.winfo_height() # canvasの高さを取得 |
---|
| | if (canv_w / canv_h) > (self.__map_img_pil.width / self.__map_img_pil.height): |
---|
| | # canvasの方が横長 画像をcanvasの縦に合わせてリサイズ |
---|
| | scale = canv_h / self.__map_img_pil.height |
---|
| | img_w = int(self.__map_img_pil.width * scale) |
---|
| | img = self.__map_img_pil.resize((img_w, self.canv_h), resample=Image.Resampling.NEAREST) |
---|
| | img = self.__map_img_pil.resize((img_w, canv_h), resample=Image.Resampling.NEAREST) |
---|
| | else: |
---|
| | # キャンバスの方が縦長 画像をキャンバスの横に合わせてリサイズ |
---|
| | scale = self.canv_w / self.__map_img_pil.width |
---|
| | # canvasの方が縦長 画像をcanvasの横に合わせてリサイズ |
---|
| | scale = canv_w / self.__map_img_pil.width |
---|
| | img_h = int(self.__map_img_pil.height * scale) |
---|
| | img = self.__map_img_pil.resize((self.canv_w, img_h), resample=Image.Resampling.NEAREST) |
---|
| | img = self.__map_img_pil.resize((canv_w, img_h), resample=Image.Resampling.NEAREST) |
---|
| | self.draw_img_tk = ImageTk.PhotoImage(img) # pilフォーマットの画像をtkinterのフォーマットに変換 |
---|
| | self.canvas.create_image(self.canv_w/2, self.canv_h/2, image=self.draw_img_tk) # 画像の描画 |
---|
| | self.update() |
---|
| | self.canvas.create_image(canv_w/2, canv_h/2, image=self.draw_img_tk) # 画像の描画 |
---|
| | |
---|
| | ## 右クリックしたときに表示するポップアップメニューを作成 |
---|
| | self.popup_menu = tk.Menu(self, tearoff=tk.OFF) |
---|
| | self.popup_menu.add_command(label="add waypoint", command=self.add_waypoint) |
---|
| | # 右クリックしたときの座標を保持する変数 |
---|
| | self.right_click_coord = None |
---|
| | self.right_click_coord = None # 右クリックしたときの座標を保持する変数 |
---|
| | |
---|
| | ## マウスイベントを設定 |
---|
| | self.master.bind("<MouseWheel>", self.mouse_wheel) |
---|
| | self.master.bind("<B1-Motion>", self.left_click_move) |
---|
| |
---|
| | return |
---|
| | |
---|
| | |
---|
| | |
---|
| | #--- Fileメニューの"Save"がクリックされたときに実行されるコールバック関数 --- |
---|
| | def menu_save_clicked(self, event=None): |
---|
| | print("Clicked \"Save\"") |
---|
| | return |
---|
| | #--- mapのファイルパスを受け取り、map画像とmapの設定ファイルを読み込む --- |
---|
| | #--- 今はパスを直接指定して読み込んでいるので、rospy.get_param()を使って読み込めるように --- |
---|
| | def get_map_info(self): |
---|
| | map_path = '..\..\waypoint_nav\maps\map' # .pgmと.yamlの手前までのパス |
---|
| | map_img_pil = Image.open(Path(map_path+'.pgm')) # .pgmをplillowで読み込む |
---|
| | with open(map_path+'.yaml') as file: # .yamlを読み込む |
---|
| | map_yaml = ruamel.yaml.YAML().load(file) |
---|
| | |
---|
| | return map_img_pil, map_yaml # この2つの変数を戻り値とする |
---|
| | |
---|
| | |
---|
| | |
---|
| | #--- Fileメニューの"Save As"がクリックされたときに実行されるコールバック関数 --- |
---|
| | def menu_saveas_clicked(self, event=None): |
---|
| | print("Clicked \"Save As\"") |
---|
| | return |
---|
| | |
---|
| | #--- これもget_param()でパスを受け取り、読み込めるようにする --- |
---|
| | def get_waypoints(self): |
---|
| | file_path = '..\..\waypoint_nav\param\waypoints.yaml' |
---|
| | with open(file_path) as file: |
---|
| | waypoints = ruamel.yaml.YAML().load(file) |
---|
| | return waypoints |
---|
| | |
---|
| | |
---|
| | |
---|
| | #--- マウスを左クリックしながらドラッグしたときのコールバック関数 --- |
---|
| | def left_click_move(self, event): |
---|
| |
---|
| | |
---|
| | |
---|
| | #--- 右クリックしたときのコールバック関数 --- |
---|
| | def right_click(self, event): |
---|
| | self.popup_menu.post(event.x_root, event.y_root) |
---|
| | self.right_click_coord = [event.x, event.y] |
---|
| | self.popup_menu.post(event.x_root, event.y_root) # メニューをポップアップ |
---|
| | self.right_click_coord = [event.x, event.y] # クリックされた座標を変数に格納 |
---|
| | return |
---|
| | |
---|
| | |
---|
| | |
---|
| | #--- マウスホイールを回転したとき(タッチパッドをドラッグしたとき)のコールバック関数 --- |
---|
| | #--- |
---|
| | def mouse_wheel(self, event): |
---|
| | if event.delta > 0: |
---|
| | # 上に回転(タッチパッドなら下にドラッグ)=> 拡大 |
---|
| | print(event.x, event.y, event.delta) |
---|
| |
---|
| | |
---|
| | #--- 右クリックしてポップアップメニューのadd waypointをクリックしたときのコールバック関数 --- |
---|
| | def add_waypoint(self): |
---|
| | print("Clicked \"add waypoint\"") |
---|
| | return |
---|
| | |
---|
| | |
---|
| | |
---|
| | #--- Fileメニューの"Save"がクリックされたときに実行されるコールバック関数 --- |
---|
| | def menu_save_clicked(self, event=None): |
---|
| | print("Clicked \"Save\"") |
---|
| | return |
---|
| | |
---|
| | |
---|
| | |
---|
| | #--- Fileメニューの"Save As"がクリックされたときに実行されるコールバック関数 --- |
---|
| | def menu_saveas_clicked(self, event=None): |
---|
| | print("Clicked \"Save As\"") |
---|
| | return |
---|
| | |
---|
| | |
---|
| | |
---|
| | |
---|
| | #===== メイン処理 プログラムはここから実行される =====# |
---|
| |
---|
| | |