Python - error when using PyVsta + Tkinter - python

I am creating a program with GUI. I use Tkinter and visualize data in 3D by PyVista.
Data is drawn in a separate window of PyVista. Everything works fine until I close the PyVista window.
At this point, the tkinter window freezes. After stopping the script, an error is generated:
Traceback (most recent call last):
File "draw.py", line 46, in <module>
event, values = window.read()
File "lib\site-packages\PySimpleGUI\PySimpleGUI.py", line 10067, in read
results = self._read(timeout=timeout, timeout_key=timeout_key)
File "lib\site-packages\PySimpleGUI\PySimpleGUI.py", line 10195, in _read
Window._root_running_mainloop.mainloop()
File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1429, in mainloop
self.tk.mainloop(n)
KeyboardInterrupt
I have read a lot of articles about this but have not found an answer. notebook=False doesn't help.
I also saw articles about VTK errors, but the error I get is not like this.
Can you help with this?

Related

PyQt5: restricting dock widget to only move inside frame

Im creating an application with PyQt5. I wanted to create a widget that lives inside a frame and that the user can move and resize at will. Following this answer i came to the conclusion that i could use QDockWidgets to do this.
Thing is: i want my QDockWidget to only exist and be movable inside a frame of my mainwindow. It seems that setAllowedAreas() could do this restriction for me but it can only be used with QtDockWidgetAreas, and preexisting areas are just default areas of the main window.
So currently my code is like this:
#!/usr/local/bin/pydm
from PyQt5.QtWidgets import QDockWidget
from pydm import Display
class Window(Display): ##Main window class.
def __init__(self, args, macros):
super(Window, self).__init__(None, args, macros,
ui_filename="main.ui")
self.pushButton.clicked.connect(self.createDock)
def createDock(self):
self.dock=QDockWidget()
self.dock.raise_()
self.dock.show()
(pydm is amodule that inherits all classes from PyQt and allows all default functionalities to work just fine.)
The main.ui file created with QtDesigner is just a widget window with a frame and a pushbutton. The generated window is in the image below:
So obviously my DockWidget can go outside the frame. I tried self.dock.setAllowedAreas(self.myFrame) but i got the expected error when clicking the button:
Traceback (most recent call last):
File "./main.py", line 16, in createDock
self.dock.setAllowedAreas(self.frame)
TypeError: setAllowedAreas(self, Union[Qt.DockWidgetAreas, Qt.DockWidgetArea]): argument 1 has unexpected type 'QFrame'
i also tried:
from PyQt5.QtCore import Qt
and in the createDock(self) function:
myArea = Qt.DockWidgetArea(self.frame)
self.dock.setAllowedAreas(myArea)
But i got:
Traceback (most recent call last):
File "./main.py", line 17, in createDock
myArea = Qt.DockWidgetArea(self.frame)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'QFrame'
Looking at the QDockWidgetArea it doesnt look that i can make a custom Area at all. At least not that i could find.
Is there any way at all to achieve the functionality that i want?

Why gdspy library give a tkinter tcl error when trying to use the layout viewer

I'm using the gdspy library which uses tkinter to show a layout preview.
But when trying to use:
gdspy.LayoutViewer(library=None, cells=[cell])
python give me a:
Traceback (most recent call last):
File ".\InductorGen.py", line 726, in <module>
gdspy.LayoutViewer(library=None, cells=[cell])
File "C:\Users\Maël\Anaconda3\lib\site-packages\gdspy\viewer.py", line 182, in __init__
self.grid(sticky='nsew')
File "C:\Users\Maël\Anaconda3\lib\tkinter\__init__.py", line 2226, in grid_configure
+ self._options(cnf, kw))
_tkinter.TclError: cannot use geometry manager grid inside . which already has slaves managed by pack
here is the code from the layout viewer of gdspy: gdspy_layoutviewer
Looking through the gdspy code, it appears that it assumes that the caller is using grid inside of the root widget. More correctly, it's assuming there are no other widgets in the root window.
It uses grid to inject itself into row zero and column zero of the root window. If your code (or Anaconda itself) is using pack in the root widget, that would explain the error that you get.

Python & Matplotlib: creating a chart first and showing it at a second moment

I'm working on a project implemented in Python 2.7 with a GUI made with PyQt4. I am trying to create a chart with Matplotlib that will be created while the main thread is running but that should be shown only when the user press on a certain button. The idea is:
def makeTheChart(self, equitycurve):
ecchart.plot(equitycurve)
This first method will be called from another class (that instatiates the object and passes the data "equitycurve" to it; the chart "ecchart" is then ready (if I would put a ecchart.show() right after it shows me the right chart);
def showTheChart(self):
ecchart.show(block=True)
The second method, instead, should be called when pressing a button on the GUI. So the problem is:
the chart is created (cause if I write "ecchart.show()" into the first function I'm gonna get the right one) but when I press on the button to call "ecchart.show()" I get the following error:
File "C:\Users\BackTest.py", line 5496, in showTheChart
ecchart.show(block=True)
File "C:\Python27\lib\site-packages\matplotlib\pyplot.py", line 143, in show
_show(*args, **kw)
File "C:\Python27\lib\site-packages\matplotlib\backend_bases.py", line 82, in __call__
manager.show()
File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 576, in show
self.canvas.draw_idle()
File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 367, in draw_idle
self._idle_callback = self._tkcanvas.after_idle(idle_draw)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 509, in after_idle
return self.after('idle', func, *args)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 502, in after
return self.tk.call('after', ms, name)
_tkinter.TclError: out of stack space (infinite loop?)
Any idea about what the problem could depend on and how to fix it? Thanks, don't hesitate ask more questions if needed
We would suggest first check {this} for working example of embedding matplotlib charts in Qt4. Also you may find it useful check {this link} where there are many working other examples.
Shortly, you may try to make invisibile your chart by using youchart.axes.set_visible(False) when you're creating it then you will be able latter to set it visible, i.e., yourchart.axes.set_visible(True). We tried this method in the example given at first link above and it worked as supposed.

Strange Exception in Tkinter callback

I'm still working on my little Tkinter project which is simple a logging console that prints incoming text from the serial line to a Text Widget with some coloring applied.
One question is open and can be found here: Python Tkinter Text Widget with Auto & Custom Scroll
However, even without manual scrolling (so I'm using self.text.yview(END) to auto-scroll to the bottom after inserting text with self.text.insert(END, str(parsed_line)).
The script actually works but every now and then it throws some "silent" exceptions within the Tkinter thread that does not let the whole application crash:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python26\lib\lib-tk\Tkinter.py", line 1410, in __call__
return self.func(*args)
File "C:\Python26\lib\lib-tk\Tkinter.py", line 2813, in set
self.tk.call((self._w, 'set') + args)
TclError: expected floating-point number but got "0.7807017543859649integer but got "end""
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python26\lib\lib-tk\Tkinter.py", line 1410, in __call__
return self.func(*args)
File "C:\Python26\lib\lib-tk\Tkinter.py", line 2813, in set
self.tk.call((self._w, 'set') + args)
TclError: invalid command name ".15427224integer but got "end""
It looks as if some method expected a an integer, returns the string integer but got "end" to a method that expected a float which is concatinated with the error message. The float number in that string looks like the position of the scrollbar that I have attached to my text widget:
(...)
scrollbar = Scrollbar(root)
scrollbar.pack(side=RIGHT, fill=Y)
text = Text(wrap=WORD, yscrollcommand=scrollbar.set)
scrollbar.config(command=text.yview)
text.pack(expand=YES, fill=BOTH)
(...)
I have the feeling that it happens when a lot of lines are inserted within a short time. But since I only have one thread interacting with Tkinter this cannot be a threading issue.
I also got very random errors like that before I had applied the str() function to parsed_line in self.text.insert(END, str(parsed_line)).
This is very strange behavior and I'm wondering if anyone could explain what this is about and how to fix it.
Thanks a lot!
mtTkinter allows multithreading with Tkinter, you can get it here:
http://tkinter.unpythonic.net/wiki/mtTkinter
Just import mtTkinter in place of Tkinter. This will allow you to insert text into a Text widget from multiple threads without conflict. I used it for some instant messaging software I wrote and it works wonderfully.

How to use python curses module to create a key event?

I'm trying to make a key event in python. I think that with curses module i can do that but i don't know how to. Please help me.
How can i call a function with a press of a keyboard key. Like, if "space" key is pressed do something, if "c" key is pressed show image, if "s" key is pressed save image. My problem is only to make that key event.
I'm using Linux o.s.
I tried to use urwid module
and when i use this code:
import PIL
import Image
im=Image.open("im.tif")
imshow(im,cmap=cm.gray ,origin=1)
import urwid
def save(input):
if input in ('s'):
savefig("im2.png")
appeared this error:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python2.6/lib-tk/Tkinter.py", line 1413, in __call__
return self.func(*args)
File "/usr/lib/pymodules/python2.6/matplotlib/backends/backend_tkagg.py", line 312, in key_press
FigureCanvasBase.key_press_event(self, key, guiEvent=event)
File "/usr/lib/pymodules/python2.6/matplotlib/backend_bases.py", line 1143, in key_press_event
self.callbacks.process(s, event)
File "/usr/lib/pymodules/python2.6/matplotlib/cbook.py", line 163, in process
func(*args, **kwargs)
File "/usr/lib/pymodules/python2.6/matplotlib/backend_bases.py", line 1703, in key_press
self.canvas.toolbar.save_figure(self.canvas.toolbar)
TypeError: save_figure() takes exactly 1 argument (2 given)
What am i doing wrong ? How can i make it work?
ps: I'm sorry for my ignorance but i'm very new in python.
Thank you for answer
Generating a keypress:
On Windows it is quite easy to generate keypresses. On Linux a bit more difficult:
The crude way: os.system('xvkbd -text "\\\\CP" ')
Alternatives:
Simulate keystroke in Linux with Python
Simulating Key Press event using Python for Linux
This module is interesting, uses a kernel module: http://codegrove.org/projects/python-uinput
Couldn't find mention of generating keypress events in curses.
Getting a key press:
Use of curses is a bit much for this case.
Something like: getting a char at a time would be simpler.
Easier than curses would be to use urwid.
Finally, the curses way: http://docs.python.org/release/2.6/howto/curses.html#user-input
Events such as you describe are usually associated with some sort of GUI container (window, canvas, frame, what have you) so "events" really don't have any meaning without some sort of GUI. I could give a more detailed answer if you would say what GUI framework you are using, but barring that, here are links descibing how to handle events using TKInter and WxPython

Categories