I am searching any simple way to make urwid.Frame work in python without success, as example, I try this MWE:
frame = urwid.Frame(urwid.Text(('some text'), align='center'))
filler = urwid.Filler(frame, "top")
loop = urwid.MainLoop(filler)
loop.run()
And I get the following unuseful error message:
Traceback (most recent call last):
File "pycurses.py", line 596, in <module>
loop.run()
File "/home/fauve/.local/lib/python3.5/site-packages/urwid/main_loop.py", line 287, in run
self._run()
File "/home/fauve/.local/lib/python3.5/site-packages/urwid/main_loop.py", line 385, in _run
self.event_loop.run()
File "/home/fauve/.local/lib/python3.5/site-packages/urwid/main_loop.py", line 790, in run
self._loop()
File "/home/fauve/.local/lib/python3.5/site-packages/urwid/main_loop.py", line 818, in _loop
self._entering_idle()
File "/home/fauve/.local/lib/python3.5/site-packages/urwid/main_loop.py", line 779, in _entering_idle
callback()
File "/home/fauve/.local/lib/python3.5/site-packages/urwid/main_loop.py", line 574, in entering_idle
self.draw_screen()
File "/home/fauve/.local/lib/python3.5/site-packages/urwid/main_loop.py", line 588, in draw_screen
canvas = self._topmost_widget.render(self.screen_size, focus=True)
File "/home/fauve/.local/lib/python3.5/site-packages/urwid/widget.py", line 145, in cached_render
canv = fn(self, size, focus=focus)
File "/home/fauve/.local/lib/python3.5/site-packages/urwid/decoration.py", line 814, in render
top, bottom = self.filler_values(size, focus)
File "/home/fauve/.local/lib/python3.5/site-packages/urwid/decoration.py", line 799, in filler_values
height = self._original_widget.rows((maxcol,),focus=focus)
File "/home/fauve/.local/lib/python3.5/site-packages/urwid/widget.py", line 205, in cached_rows
return fn(self, size, focus)
File "/home/fauve/.local/lib/python3.5/site-packages/urwid/container.py", line 1611, in rows
return sum(self.get_item_rows(size, focus))
File "/home/fauve/.local/lib/python3.5/site-packages/urwid/container.py", line 1512, in get_item_rows
l.append(w.rows((maxcol,),
AttributeError: 'Frame' object has no attribute 'rows'
I try many variations, such putting the frame inside an urwid.Pile before giving it to the Filler widget, but I still get similar error messages.
So, is their any minimalist example work using urwid.Frame?
And what doese mean this “Frame' object has no attribute 'rows'”? I never ask in my example any .rows method, so why the error message have a behavior like if I used it?
The error is indeed not very good. The actual problem here is that the nesting of the Frame and the Filler should be the other way around:
import urwid
text = urwid.Text('some text', align='center')
filler = urwid.Filler(text, "top")
frame = urwid.Frame(filler)
loop = urwid.MainLoop(frame)
loop.run()
A flow widget (like Text) gets to decide how many rows it should be. The main loop expects a box widget (which does not get to pick its own width or height). The Filler widget bridges the two: it asks the wrapped flow widget how many rows it takes up (given a number of columns) and then fills up the rest of the rows.
The Frame is a box widget that contains another box widget in the center.
If you haven't seen this page already, I highly recommend looking at the diagrams here: http://urwid.org/manual/widgets.html#included-widgets The colors describe what kinds of widgets nest inside what kinds of widgets.
(Also I suspect it would be technically feasible for Urwid to detect that the widget is of the wrong type and say that instead in the error message, but I haven't dived that deep into the implementation.)
Related
I simplified my code so it can be reproduced. The "select empty template file" popup can be any file. I did contact the author of uszipcode and he is super nice and told me that the way I'm using tkinter is causing the problem and that I should put my core logic inside the def of button to avoid it. However, I wish to only use tkinter to obtain file names. Even though there is an exception message, I still get all the results I want.
(My full code is about minimizing shipping distance: say I have fileone contain 10000 orders with order detail and zipcodes, filetwo contain the location of 100 warehouses and their zipcodes, and filethree contain the formatting template for warehouses. I used tkinter to obtain these three filenames, write the data in dataframes, and then calculate the nearest zipcode distance from 100000 orders to the 100 warehouses and choose the closest warehouse, and convert the order details to the formatting that warehouses need.) I would be very grateful for your inputs or feedbacks!
from tkinter import filedialog
from tkinter import *
import tkinter as tk
def browse_button3():
global folder_path3
filenameq3 = filedialog.askopenfilename()
folder_path3.set(filenameq3)
print(filenameq3)
root = tk.Tk()
folder_path3 = StringVar()
lbl1 = Label(master=root,textvariable=folder_path3)
lbl1.grid(row=1, column=3)
button3 = Button(text="\n Select Empty Template File \n Select Empty Template File \n Select Empty Template File \n", command=browse_button3,bg='green', fg='black',)
button3.grid(row=1, column=3)
root.mainloop()
from uszipcode import SearchEngine
engine = SearchEngine()
zipp=engine.by_zipcode('46067')
coords_1 = (zipp.lat, zipp.lng)
print(coords_1)
Exception ignored in: <function SearchEngine.__del__ at 0x000002B520053040>
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\site-packages\uszipcode\search.py", line 196, in __del__
File "C:\ProgramData\Anaconda3\lib\site-packages\uszipcode\search.py", line 202, in close
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\orm\session.py", line 1757, in close
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\orm\session.py", line 1799, in _close_impl
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\orm\session.py", line 923, in close
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 2287, in close
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 2503, in _do_close
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 2489, in _close_impl
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 2481, in _connection_rollback_impl
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 960, in _rollback_impl
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1995, in _handle_dbapi_exception
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\util\compat.py", line 207, in raise_
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 958, in _rollback_impl
File "C:\ProgramData\Anaconda3\lib\site-packages\sqlalchemy\engine\default.py", line 667, in do_rollback
sqlalchemy.exc.ProgrammingError: (sqlite3.ProgrammingError) Cannot operate on a closed database.
I'm trying to write a tkinter program, and I came across an error that I've never seen before while working with tkinter. I've searched around everywhere, and tried everything I can think of. This is my code so far:
x=tk.Canvas(top,width=1000,height=750,bg="grey")
x.pack()
y=tk.PhotoImage(file="C:\\Users\\Admin\\Desktop\\images (3)_CnyokaDvJmG1xu.png")
x.create_image(top,0,0,image=y)`
and this is error
Traceback (most recent call last):
File "C:\Users\Admin\Anaconda3\lib\tkinter\__init__.py", line
1705, in __call__
return self.func(*args)
File "C:/Users/Admin/.spyder-py3/temp.py", line 16, in open
x.create_image(top,0,0,image=y).pack()
File "C:\Users\Admin\Anaconda3\lib\tkinter\__init__.py", line
2489, in create_image
return self._create('image', args, kw)
File "C:\Users\Admin\Anaconda3\lib\tkinter\__init__.py", line
2480, in _create
*(args + self._options(cnf, kw))))
_tkinter.TclError: bad screen distance "."
You don't have to supply containing widget when placing an image in a canvas, coordinates are enough:
x.create_image(0,0,image=y)
The error is because canvas does not accept a widget as coordinates.
I am facing a strange problem.
I changed a piece of python2 I had to python3 using 2to3.
After this, my code is randomly running/failing...
The Error I get when it fails is related to an Attribute Error...
But in python2 and in random python3 trials it works, and find the attribute...
I tested this behavior on 2 machines, running both python3.4.
Would you have any clue of what is going wrong (I am puzzled by this "random" failure) ?
Here is the trace I get :
Traceback (most recent call last):
File "tools/ciregs.py", line 1596, in <module>
module = Module(json_data)
File "tools/ciregs.py", line 1147, in \__init__
self.registers = [Register(json_reg, parent_module=self) for json_reg in json_module[key]]
File "tools/ciregs.py", line 1147, in <listcomp>
self.registers = [Register(json_reg, parent_module=self) for json_reg in json_module[key]]
File "tools/ciregs.py", line 1260, in \__init__
self.fields = [Field(json_field, self) for json_field in json_reg[key]]
File "tools/ciregs.py", line 1260, in <listcomp>
self.fields = [Field(json_field, self) for json_field in json_reg[key]]
File "tools/ciregs.py", line 1443, in \__init__
self.check()
File "tools/ciregs.py", line 1453, in check
if(self.bitWidth <= 0 or self.bitWidth > self.parent_reg.size()):
File "tools/ciregs.py", line 1326, in size return self.parent_module_.width
AttributeError: 'Module' object has no attribute 'width'
I have a dictionary that contains a "width" key. In a sub-element, I want to evaluate the size of the said sub-element against the width of the top to see if it fits.
That's why I try to access to self.parent_reg.size() that access to the width and that randomly issues that attribute width doesn't exist in the top level dictionary.
Thanks for your help!
Ok guys, thanks for your help, #Bryan Oakley, your help helped me.
In the end the problem is that I get my keys from a json I load, and the load was done on a dictionary and not a sorted dictionary.
One of my key, last in json, then calls functions that expect other keys (width in the Error reported) to be set.
Having the dictionary not sorted makes the width key to be set in some cases before the setting of the last key, and not set in some other cases.
I am still puzzled why it worked for python2....
Thanks all for your help !
When I typed the following code as per the Think Python text book, I'm getting the error message below.
The window does actually get displayed, but it doesn't contain the desired content.
from swampy.World import World
world=World()
world.mainloop()
canvas = world.ca(width=500, height=500, background='white')
bbox = [[-150,-100], [150, 100]]
canvas.rectangle(bbox, outline='black', width=2, fill='green4')
The error message was like this:
Traceback (most recent call last):
File "15.4.py", line 4, in <module>
canvas = world.ca(width=500, height=500, background='white')
File "/usr/local/lib/python2.7/dist-packages/swampy/Gui.py", line 244, in ca
return self.widget(GuiCanvas, width=width, height=height, **options)
File "/usr/local/lib/python2.7/dist-packages/swampy/Gui.py", line 359, in widget
widget = constructor(self.frame, **widopt)
File "/usr/local/lib/python2.7/dist-packages/swampy/Gui.py", line 612, in __init__
Tkinter.Canvas.__init__(self, w, **options)
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 2234, in __init__
Widget.__init__(self, master, 'canvas', cnf, kw)
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 2094, in __init__
(widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: can't invoke "canvas" command: application has been destroyed
The main application loop needs to be pretty much the last thing you run in your application. So move world.mainloop() to the end of your code like this:
from swampy.World import World
world = World()
canvas = world.ca(width=500, height=500, background='white')
bbox = [[-150, -100], [150, 100]]
canvas.rectangle(bbox, outline='black', width=2, fill='green4')
world.mainloop()
What happens in your code is that when the line with world.mainloop() is hit, it builds the user interface elements and goes in to the main loop, which continuously provides your application with user input.
During it's lifetime, that main loop is where your application will spend 99% of its time.
But once you quit your application, the main loop terminates and tears down all those user interface elements and the world. Then the remaining lines after the main loop will be executed. In those, you're trying to build and attach a canvas to a world that has already been destroyed, hence the error message.
I have a grid layout and am adding to it some CoreImage widgets that I want to use for displaying pictures. I chose not to use uix.image since CoreImage is faster and I want to swap between a few pictures often.
When I do self.add_widget(CoreImage('Transparent.png')) my program will crash.
Traceback (most recent call last):
File "/path/to/my/app.py", line 1030, in <module>
MyApp().run()
File "/usr/lib/python2.7/dist-packages/kivy/app.py", line 798, in run
root = self.build()
File "/path/to/my/app.py", line 702, in build
self.build_grid()
File "/path/to/my/app.py", line 696, in build_grid
self.grid.build_self()
File "/path/to/my/app.py", line 134, in build_self
self.add_widget(CoreImage('Transparent.png'))
File "/usr/lib/python2.7/dist-packages/kivy/uix/layout.py", line 80, in add_widget
size_hint=self._trigger_layout)
File "_event.pyx", line 436, in kivy._event.EventDispatcher.bind (kivy/_event.c:5429)
KeyError: 'size_hint'
What am I doing wrong? This works fine when I used uix.image.
I tried to do the same for showing a bunch of memory-loaded images. Something like this came out:
from kivy.uix.image import Image
from kivy.core.image import Image as CoreImage
self.add_widget(Image(texture=CoreImage('Transparent.png').texture))
Hope it helps.
kivy.core.image.Image (I assume this is what you mean) is not a widget, you can't use it like this. Use kivy.uix.image.Image.