TomSchimansky / TkinterMapView

A python Tkinter widget to display tile based maps like OpenStreetMap or Google Satellite Images.
Creative Commons Zero v1.0 Universal
621 stars 85 forks source link

Create map widget on Toplevel window #65

Closed akrish1998 closed 1 year ago

akrish1998 commented 1 year ago

Hi,

I'm currently using tkintermapview version 1.19 and python 3 version 3.9.6 and I'm running the following code but I'm seeing a blank map:

import tkinter
import tkintermapview

# create tkinter window
root_tk = tkinter.Tk()
root_tk.geometry(f"{800}x{600}")
root_tk.title("map_view_example.py")

# create map widget
map_widget = tkintermapview.TkinterMapView(root_tk, width=800, height=600, corner_radius=0)
map_widget.place(relx=0.5, rely=0.5, anchor=tkinter.CENTER)

root_tk.mainloop()

image

Is there something I can do to see the map correctly?

Thanks

TomSchimansky commented 1 year ago

I don't know what's the problem there, for me everything is working fine on Windows. What you can do is search the following url in your browser and see if you receive a valid tile image or an error message:

https://a.tile.openstreetmap.org/0/0/0.png
Dogeonetundra32 commented 1 year ago

the map is working when i call it outside a function.

from tkinter import*
import tkintermapview

self=Tk()
my_label=LabelFrame(self)
my_label.place(x=0,y=100)

map_widget=tkintermapview.TkinterMapView(my_label,width=1270, height=500, corner_radius=20)
map_widget.pack()
self.mainloop()

this works and successfully brings up the map

from tkinter import*
import tkintermapview
win=Tk()
def map_win():
    import tkintermapview
    winmap=Tk()
    winmap.title("Set Location")
    winmap.geometry("1366x768")

    my_label=LabelFrame(winmap)
    my_label.pack(pady=20)

    map_widget=tkintermapview.TkinterMapView(my_label,width=800,height=600)
    map_widget.pack()
    winmap.mainloop()
next_btn=Button(win,text="next",height=2,width=20, command=map_win)
next_btn.place(x=450,y=476)
win.mainloop()

The above code does not work and the resultant window which opens on the click of the button looks like this: image and returns the following error:

"C:\Users\User\AppData\Local\Programs\Python\Python311\Lib\tkinter__init__.py", line 2832, in _create return self.tk.getint(self.tk.call( ^^^^^^^^^^^^^ _tkinter.TclError: image "pyimage3" doesn't exist

My use case requires me to open the map window using a button , whose command is to create a new window which contains the map. Is there anything i can do to fix it?

Thanks in advance!

freesh78 commented 1 year ago

I am also facing the same issue, the map isn't showing up properly and instead ,showing a blank space.

TomSchimansky commented 1 year ago

That's not how you create a secondary window in tkinter. This cannot work. There should only be one instance of Tk() and mainloop() can only be called once. You should create a toplevel object like this:

import tkinter
import tkintermapview

def map_win():
    toplevel_window = tkinter.Toplevel()
    toplevel_window.title("Set Location")
    toplevel_window.geometry("1366x768")

    my_label = tkinter.LabelFrame(toplevel_window)
    my_label.pack(pady=20)

    map_widget = tkintermapview.TkinterMapView(my_label, width=800, height=600)
    map_widget.pack()

app = tkinter.Tk()
app.geometry("800x600")

next_btn = tkinter.Button(app, text="next", height=2, width=20, command=map_win)
next_btn.place(x=450, y=476)

app.mainloop()

But that's also not how you would create such an app with a secondary window. Because with the method above you create a new window every time you press the button and that's not how it should be. With the following object oriented approach, you can create only one map window at a time and that's also the architecture of how I would do such an app:

import tkinter
import tkintermapview

class MapWindow(tkinter.Toplevel):
    def __init__(self):
        super().__init__()
        self.title("Set Location")
        self.geometry("1366x768")

        self.my_label = tkinter.LabelFrame(self)
        self.my_label.pack(pady=20)

        self.map_widget = tkintermapview.TkinterMapView(self.my_label, width=800, height=600)
        self.map_widget.pack()

class App(tkinter.Tk):
    def __init__(self):
        super().__init__()
        self.geometry("800x600")

        self.next_btn = tkinter.Button(self, text="next", height=2, width=20, command=self.open_map_window)
        self.next_btn.place(x=450, y=476)

        self.map_window = None

    def open_map_window(self):
        if self.map_window is None or not self.map_window.winfo_exists():
            self.map_window = MapWindow()  # create new window
        else:
            self.map_window.lift()  # bring already existing window to the top

app = App()
app.mainloop()