I've recently discovered Tkinter and its uses, but it only works when we run it from IDLE (file > open > F5)
I'd like to use it from the cmd window but it doesn't open the tkinter window and canevas
is there any way to open a python file from the cmd window as IDLE would have done it ?
IDLE executes a file nearly the same as python -i path/file.py -- notice the -i. The result is that tkinter windows are left on screen, and can be interacted with, after file.py execution stops. This is really handy for development. You likely have to add -i to your command line (if still developing), or add root.mainloop() (or the equivalent) at the end of your program. (There are parts of tkinter that do not work with .mainloop omitted, even in IDLE, but many part do.)
In 3.x, it is possible to write an import that works in IDLE and fails at the command line. But you did not mention getting an ImportError traceback.
If neither of these is your problem, then create and post a truly minimal working example, along with answers to Bryan's questions.
Related
I'm asking help today because I'm new to Tkinter and Pyinstaller (and python in general) and I'm having troubles with it.
I have a simple app working with sqlite, tkinter and pyinstaller to compile all of this in an executable program, the entrance point of my program is a file named main.py
This file calls all the dependancies (like the sqlite module for python, tkinter and my other files like classes etc...)
I made a very simple interface, with a Hello World in a tkinter label and a button to go to page 2 which displays page2 (also in a label), just to see if I'm capable of making it all run and compile all of these pieces together.
I can run it throught my shell executing it like : python main.py and everything is working fine.
But when I run pyinstaller on my linux machine, and start executing the program, nothing appears, my database.db (sqlite database file) is created but I don't have any interface like when I run it with my shell. The thing is getting even worse on windows where, once I've my .exe it just opens a shell and crash after few seconds, not even creating the database.
What I did is I created a 'log file', in which I write the steps of the program.
As you can see on the following picture, the 2 first prints are wrote in my log file (on linux), so I think it crashes when I try to create the window.
If any of you have an idea on what I do wrong, I would really appreciate help :)
General
From the PyInstaller manual:
Before you attempt to bundle to one file, make sure your app works correctly when bundled to one folder. It is is much easier to diagnose problems in one-folder mode.
As the comments suggested, use a catch-all try/except block to log all exceptions to a file. That is probably the best way to see what is really happening. Make sure that the logfile is created in an existing location where you have the necessary permissions.
I would suggest to take advantage of the built-in logging module instead of creating your own. It can e.g. automatically add from which file a log line was created.
IMHO, it is probable that the failures on Linux and ms-windows have completely different causes. You should probably treat them as different issues.
Linux
When you use single file mode, that file is unpacked into a temporary folder, probably somewhere in /tmp. Some Linux distributions mount the /tmp filesystem with the noexec flag. This is incompatible with PyInstaller.
ms-windows
On windows, there are basically two different Pythons; python.exe and pythonw.exe. Basically it is one of the quirks of windows that this is necessary. The latter is for GUI programs like tkinter programs. A tkinter script should not show a cmd window. So I'm guessing that PyInstaller calls your command with python.exe instead of pythonw.exe. From the manual:
By default the bootloader creates a command-line console (a terminal window in GNU/Linux and Mac OS, a command window in Windows). It gives this window to the Python interpreter for its standard input and output. Your script’s use of print and input() are directed here. Error messages from Python and default logging output also appear in the console window.
An option for Windows and Mac OS is to tell PyInstaller to not provide a console window. The bootloader starts Python with no target for standard output or input. Do this when your script has a graphical interface for user input and can properly report its own diagnostics.
As noted in the CPython tutorial Appendix, for Windows a file extention of .pyw suppresses the console window that normally appears. Likewise, a console window will not be provided when using a myscript.pyw script with PyInstaller.
Also, on windows it can matter which Python distribution you're using. I used to be a fan of Anaconda, but lately I've come to prefer the python.org version because it gives me less headaches. On anaconda Python I had the problem that tkinter programs would not launch without showing a cmd window, whatever I tried. Only switching to python.org Python solved that problem.
I am an experience programmer, but relatively new to Python.
I have developed a fairly complex Python program on Raspberry Pi - in thonny, Raspbian/buster v10 - Python 3.7.3.
It uses tkinter, and works fine in thonny, but fails to create anything when the .py script is run from the command line.
I have reduced the program to a bare minimum, and it behaves the same:
:Run from thonny it works - I get the tkinter window
:Invoke python3 from CLI and enter commands individually - also works
But if I have it running in a script (test.py), the script runs fine (I get output) but no window appears.
import tkinter
root = tkinter.Tk() #produces small window in thonny & python3-line-by-line
#but nothing when the test.py script is run
print ('test") #to prove program is actually running
while 1: #loop to stop program terminating
l=3
No error messages.
Try to add root.mainloop() at the end of your code
The answer wasn't root.mainloop() exactly, because that would block any other code - but it pointed me in the right direction and I looked at root.update and root.update_idletasks .
I've pulled all the slide/canvas updates into a single function and added update/update_idletasks and it works in both thonny and via the command line.
Thanks for a very quick fix!
Tkinter applications need to be able to process a steady flow of events. Tkinter is single threaded (meaning: it can only do one thing at a time). By creating that infinite loop you've made it impossible for tkinter to service any events and thus the window will appear frozen (or not appear at all, since the drawing of the window is itself a response to an event).
You should remove your while loop and replace it with a call to root.mainloop().
Try using pycharm. I just fixed that problem. I realized that jupyter won't work
Had the same issue. I was trying to execute following command: $ python PATH_TO_PYTHON_SCRIPT. This always failed. The correct way to launch the script was $python3 PATH_TO_PYTHON_SCRIPT.
I have set F2 prompt key with map <f2> :w<cr>:! D:\Python34\python %<cr>,when i open an python file in vim and press F2,the python file will be executed .For a simple example,
here is my python file and opened in gvim .
Now i can't input other python lines ,only thing i can do is to see the result and hit any key to close this window.
What i want is :
when i press F2, (the python file was opened in gvim) ,the python console pop up,and all the files in the python file were copied into the python console automatically,and i can go no to input some lines such as Obj().hello in the python console or go on to edit in gvim ,i am a lazy man ,the gvim and python console all opened waiting to serve me , can i write a vim scripts to achieve the target?
The command :!D:\Python34\python -i % works fine ,i got the ouput
There is still a problem remain,
1)when command :!D:\Python34\python -i % works ,the gvim window will be frozen , i can't drag my mouse to see codes in vim.
2)there is no any python codes in the python console wiondow
So if the program is full of many lines ,and i can't remember the previous content ,worse still, the gvim window frozen ,how can i get the codes?
Avoid blocking
To make the call asynchonous (to avoid that GVIM is blocked during the Python session), use the Windows-specific :!start command:
nnoremap <f2> :w<cr>:!start D:\Python34\python -i %<cr>
List teh codez
I don't know whether it is possible to list the passed source code from the interactive Python debugger. But you can print the file contents before starting it:
nnoremap <f2> :w<cr>:!start cmd /c type % && D:\Python34\python -i %<cr>
Additional tips
You should use :noremap; it makes the mapping immune to remapping and recursion.
As your mapping only works correctly from normal mode, use :nnoremap (or extend it to support visual-mode selections, too).
Maybe Vim plugin Conque will solve your problem:
Installation instrucions are here https://code.google.com/p/conque/
To use just type :ConqueTermVSplit python -i test.py (VSplit is for vertical split - you may use horizontal)
There is no blocking of your window with python code - you may escape interactive mode and switch to your window with Ctrl+W twice
You could approach the problem from the Python angle (2.7).
Keep the file where it is (or save it with some unique name to a temporary directory) and have python load the file directly.
Go to that location in your shell and run python interactively (or have vim spin off an interpreter for you)
Import your file import demo
Experiment with what you have implemented demo.SomeModule().meth()
Make some changes in vim
Reload your python module reload(demo)
Experiment with your code again demo.SomeModule().differentMeth()
You can also have vim create a file with shortcut functions for loading/reloading the file you are working on. When vim kicks off the interpreter, you can have it set this file to the PYTHONSTARTUP environment variable, which is a file the interpreter will automatically load when it starts up. For example, you could have a function called r() to automatically reload the file you are working on.
It's also worth mentioning that reloading modules can be a little weird. If you instantiate some modules then reload the file, only new modules will use the new code; the old modules will run with the old code.
when using pdb in gvim by executing
:!python %
the window that shows the progress of PDB will gradually scroll out the window that shows the whole python scripts. but sometimes I need to have a quick glance at the entire scripts. I know by typing l at PDB command prompt
can show where the current debugging point is but it is still not able to browse the whole context.
I also tried to run pdb with two windows open but both of them will be scroll out by PDB window.
do you have any ideas that I can debug python script from one window while show the entire script from another window in gvim? If there is not such solution how to you cope with the problem (want to have a look at the script when debugging)
thanks a lot!
I have a weird issue on a friends machine where when they run my script, it only flashes the command window when it hits a line that does something with os.system. It seems to not show the command window at all otherwise. Not showing is fine, but my script does a large process and it causes the window to flash a lot.
Normally on my machine, when I open the script (that launches a gui with tkinter) the command window will open as well in the back. This is what I am trying to get my friends to do, but I do not know what would cause the command window to not show. Is there a setting within python somewhere that doesn't show the command window (unless of course it needs to run a process in it)?
Edit: Ok I did a really lame hack to fix this. Apparently all he .py files got associated with pythonw. I was unable to get this association changed (even going through the command prompt ASSOC) So I just did a silly renamed of the pythonw to old_pythonw, and renamed the python.exe to pythonw.exe. Yes, really silly but no time to argue with windows about file associations.