Perl Tk update(redraw) widgets in sub(in thread) - multithreading

I have some widgets, checkboxes actually. And I have variables that contains their value. I have shared this variables and called a sub with creating new thread.
Variables change into this sub but look of widgets stays unchanged. So that is the question: how colud I redraw widgets or update their look somehow... or how could I rebuild my programm so they will update automatically or something.
Thank you!

Using threads and Tk is not easy. See Perl Tk and Threads on PerlMonks for tips and tricks.
Do you really need threads? Using Tk::after or $widget->update you can usually update widgets to changing values.

Related

Nested functions inside a class in tkinter python [duplicate]

Consider below example:
import tkinter as tk
root = tk.Tk()
root.title("root")
other_window = tk.Tk()
other_window.title("other_window")
root.mainloop()
and also see below example that creates instances of Tk back-to-back instead of at once, so there's exactly one instance of Tk at any given time:
import tkinter as tk
def create_window(window_to_be_closed=None):
if window_to_be_closed:
window_to_be_closed.destroy()
window = tk.Tk()
tk.Button(window, text="Quit", command=lambda arg=window : create_window(arg)).pack()
window.mainloop()
create_window()
Why is it considered bad to have multiple instances of Tk?
Is the second snippet considered a bit better, or does it suffer from
the same conditions the first code does?
Why is it considered bad to have multiple instances of Tk?
Tkinter is just a python wrapper around an embedded Tcl interpreter that imports the Tk library. When you create a root window, you create an instance of a Tcl interpreter.
Each Tcl interpreter is an isolated sandbox. An object in one sandbox cannot interact with objects in another. The most common manifestation of that is that a StringVar created in one interpreter is not visible in another. The same goes for widgets -- you can't create widgets in one interpreter that has as a parent widget in another interpreter. Images are a third case: images created in one cannot be used in another.
From a technical standpoint, there's no reason why you can't have two instances of Tk at the same time. The recommendation against it is because there's rarely an actual need to have two or more distinct Tcl interpreters, and it causes problems that are hard for beginners to grasp.
Is the second snippet considered a bit better, or does it suffer from the same conditions the first code does?
It's impossible to say whether the second example in the question is better or not without knowing what you're trying to achieve. It probably is not any better since, again, there's rarely ever a time when you actually need two instances.
The best solution 99.9% of the time is to create exactly one instance of Tk that you use for the life of your program. If you need a second or subsequent window, create instances of Toplevel. Quite simply, that is how tkinter and the underlying Tcl/Tk interpreter was designed to be used.
I disagree with the tkinter community discouraging the use of multiple tk.Tk windows. You can have multiple tk.Tk windows. Using multiple instances of tk.Tk is the only way to create windows that are truly independent of each other. The only mistake most people make when creating multiple tk.Tk windows is that they forget to pass in master=... when creating PhotoImages/StringVars/IntVars/...
For example look at this code:
import tkinter as tk
root = tk.Tk()
root2 = tk.Tk()
variable = tk.StringVar() # Add `master=root2` to fix the problem
entry = tk.Entry(root2, textvariable=variable)
entry.bind("<Return>", lambda e: print(repr(variable.get())))
entry.pack()
root.mainloop()
The code above doesn't work. If you add master=root2 to the tk.StringVar(), then it will work perfectly fine. This is because tkinter stores the first instance of tk.Tk() in tk._default_root. Then if you don't pass in master=..., it will assume that you wanted the window in tk._default_root.
Another thing people get wrong is how many times should .mainloop() be called. It handles events from all tk.Tk windows that are alive so you only need one .mainloop().
For folks who disagree, I'd be interested in an example of where an actual problem is caused by the multiple tk.Tk windows.
The best reference I've found so far is the Application Windows section of the tkinterbook:
In the simple examples we’ve used this far, there’s only one window on the screen; the root window. This is automatically created when you call the Tk constructor
and
If you need to create additional windows, you can use the Toplevel widget. It simply creates a new window on the screen, a window that looks and behaves pretty much like the original root window
My take on it is that a Tk instance creates a Toplevel widget, plus things like the mainloop, of which there should be only one.
Tk() initializes the hidden tcl interpreter so that the code can run, as Tkinter is just a wrapper around tcl/tk. It also automatically creates a new window. Toplevel() just creates a new window, and wont work if Tk() hasn't been instantiated, as it requires the tcl interpreter that Tk() initializes. You cannot create any Tkinter widgets without instantiating Tk(), and Toplevel is merely a widget. In the question, you use Tk() to create a second window. You should instead create another file, because initializing the tcl interpreter multiple times can get confusing, as #Bryan Oakley explains so well. Then you should do:
from os import startfile
startfile(nameOfTheOtherFile)
, because, as Toplevel() is just a widget, it closes when the Tk() window is closed. Having the other window in a separate file makes it less confusing.

Python 3 & Tkinter buggy and slow

So, a few months back I made a small GUI for handling NPCs in a roleplaying campaign I was running. I haven't touched in since then, except that now I need it! Tomorrow, in fact...
I have a few odd error... Loading the GUI seems to work fine, but when I start to press buttons the troubles start. It seemed, at first, that it the script was very slow, which it shouldn't be, calling a two line dice function on a button press. I accidentally figured out that when I hover the mouse over the "close/minimize window" buttons (not in the GUI, but in the OS), the button would update with the result of the button press.
The same thing happens with a listbox I have: choosing an item may or may not select the item straight away (but hovering over the close/minimize updates it), and the results of the selection may or may not show. The results is in fact weirder: selecting a listbox item is supposed to get info from the selected item and print it in another frame. Even if the selection itself is fine without hovering, the printed text is somehow "clipped", showing only an area seeming to cover an arbitrarily sized square of text... Remedied by hovering, of course. The rest of the GUI have the exact same problems.
I have no clue what is going on here. The script was written on another computer, but that was also a Mac running the same OSX version (Mavericks), and it was a MUCH slower computer. This script shouldn't need any sort of advanced specs, though! I'm guessing it's something wrong with migrating to the new computer and the various version of different software? I'll paste the script down below, in case that'll help somehow.
Any help would be greatly appreciated, especially if it comes before the next epic campaign of Superheroes starts tomorrow afternoon! =P
[UPDATE]:
It was some time ago, but I still would like to have this problem solved. I've reduced my script to just a simple button, and the problem persists: clicking the button, even though there is no function or anything associated with it, only results in the frozen "button-clicked"-colour (i.e. light blue on OSX Yosemite), and I have to hover my mouse pointer over the close/minimize/etc. buttons in the top left corner to make it go back to "idle-button"-colour (i.e. grey).
#!/usr/bin/python
import tkinter as tk
root = tk.Tk()
test = tk.Button(root, text='test')
test.pack()
root.mainloop()
So, the problem obviously isn't with any of my "downstream" scripting, but something with the module or my way of calling it. Calling the script for the Terminal doesn't give me any error messages, and the problem is still there. Any ideas? It would be really, really good to get to the bottom of this problem!
I had the same problem when using Tk 8.5.13 on Mac OS X Sierra (10.12.3) with Python and IDLE v3.6.0.
Upgrading to TCL/Tk 8.5.18.0 as recommended on the Python Software Foundation page https://www.python.org/download/mac/tcltk/#activetcl-8-5-18-0 seemed to do the trick. This was the recommended version for my edition of the OS.
The interface I was building starting responding as I would expect, i.e. straight away when one of the controls was used. The only reservation I have so far is that normal buttons don't seem to have any sort of animation now, although the buttons do actually work.
-S.

Pygame, two windows one releated to other (Menu-like)

I am wondering if it is possible to create two windows in two different .py files where the first window will be some settings about the game, and the second the game with the setting, set by the user in the first window.
The first screen, it would be something easy, like 3 texts where the user can choose with the arrows. And when one of the three texts pressed, the game will be load on the screen.
Thanks
I think you want to create a window where a user can choose the resolution, or other settings, with a play button.
I would recommend Tkinter for the job.
Here you will find some tutorials about it.
You should then link a button with launching of the game itself.
EDIT:
Since you want to use pygame, this is still possible. Just have 2 seperate pygame scripts, and launch the second script after a MOUSE_DOWN event on one of the texts.
If by two windows you mean two separate windows, then no, PyGame can't do that yet.
This feature was only just added in SDL2, and I hardly think PyGame is using SDL2 yet.
If you want to use SDL2 with Python, then have a look at PySDL2: http://pysdl2.readthedocs.org/en/latest/tutorial/pygamers.html
It is suggested that you can fake it using multiprocessing: Creating multiple screens in pygame
If you want two different applications (a launcher and the game), then that shouldn't be much trouble. Just treat them as two separate PyGame applications.

How do I create a X-windows window independent of the current window manager?

I am playing with X-windows, Xlib, etc. I want to create a X-window independent of the window-manager: meaning that I do not want the WM to put a frame, minimize-maximize, close, menu, title-bar, etc. in the window. I want to create a vanilla X window. How?
[edit]
Alternatively, how to I capture those events so my windowing app can at least die without an error?
[edit] ninjalj's answer led me to the following info:
ICCCM
Lots & lots of info :) cool!
Tutorial
I think what you want is an override-redirect window. Just set the override-redirect on your XSetWindowAttributes struct (and the corresponding bit on valuemask) when creating the window.

How to move private fields to the top of the class with ReSharper

I want to move all the private fields in a class to the top or at least to a block where they are gathered together.
Is there any quick way to achieve this with ReSharper?
You want the feature called Cleanup Code.
You can access it via
CTRL+ALT+F, according to my keyboard shortcuts, or
the window menu Resharper | Code | Cleanup code...
Ensure that your profile has the option Reorder members selected. If you want to change the way that the reordering works, you can, but it's a little involved.
You can also apply this across an entire project or the entire solution by right-clicking at the appropriate level in solution explorer and choosing the Cleanup Code... option from there.
I answered a similar question here. It's for putting them at the bottom, but should be enough information to get you set up too.
Have you tried the Clean code options?
I believe you can set the behaviour there.
Kindness,
Dan

Resources