PySimpleGui - window size doesnt autofit dynamically - python

I'm trying to auto resize a PySimpleGUI window.
consider the following:
import PySimpleGUI as sg
CommandWindow = sg.Multiline(size=(80,20),echo_stdout_stderr=True,key=OUTPUT_KEY,visible=False)
window = sg.Window("FOO", layout=[CommandWindow],element_justification='center')
when the event is triggered, a sg.Multiline element's visible trait is updated to True.
then I refresh the window and it resizes (expands) to fit the element shown inside.
when I change the visible trait to False again, the window maintain its size and doesnt shrink back.
the execution as follows:
window[OUTPUT_KEY].update(visible=True/False)
window.refresh()

I think this will perhaps be the best answer I can come up with since StackOverflow answers do not age well, especially for the PySimpleGUI project which is ever-evolving.
The Demo Browser utility is made specifically to help answer questions like this. Of course, the documentation should also be used (PySimpleGUI.org).
The Demo Programs serve many purposes. One is to show specific techniques. The Demo Browser is a way for you to quickly and easily search, edit, and execute this code.
The attached screenshot is what I see when searching for "shrink" using this tool (as of Aug 2022...). The first item answers this specific issue. Maybe I got lucky? "I would rather be lucky than good". The docs and tools provided with PySimpleGUI are the best place to turn for questions rather than SO. They'll be the most accurate, the most up to date, and are part of the project itself.
Good lucky Jedi!

what solved it for me, Thanks to #Mike from PSG,
is using:
sg.Pin(,shrink=True)
as shown in docs: https://www.pysimplegui.org/en/latest/call%20reference/#layout-helper-funcs

Related

Is it possible to set activeforeground/activebackground using customtkinter?

I am able to use activeforeground and activebackground to change color in background/text when button is clicked in tkinter.
Is it possible to do the same thing in customtkinter as well? I have checked the website if similar context is available, however, could not see any.
Thanks in advance.
From both the documentation and the GitHub webpage, I could not see any changes that would suggest this is possible.
You cannot have it on the button event function, so that the moment the button is clicked, the background and foreground is changed and then it is changed back to the normal. This is beacuse the the switch will be too fast and it does not work if you add sleep().
The closest work around that you can have is probably just to have it on the hover event as I belive the Hover event may be interfering with the changing of the colour in runtime straight away. If this is a deal breaker you may want to use PySide2/6 instead as they do have this exact custimastion readily availabe.
Also for anyone else interested in Custom Tkinter, make sure to use the GitHub page to see any progress or fucntions as it is mantained, the best documentation is from the Wiki found at:
https://github.com/TomSchimansky/CustomTkinter/wiki

How to open a window by clicking on a specific point on a chart?

I have the task to build up an interactive plot which i have already done more or less. But now I am supposed to give specific information about a point in a graph for example P(8|6) and by clicking on this point there should open a new window with specific information. Adding the information to the window wont be the problem but the window itself. How I can open a window by clicking on this specific point (keep in mind, it is no button since it changes from graph to graph)?
The answer is qwt! Study the documentation and examples for that project like your life depended on it, and you will find exactly what you need.
I wrote up a pretty complete example a year or so ago; but it is in C++; converting it to python should be pretty straight forward.
https://github.com/peteristhegreat/qwt_generic
Hope that helps.

matplotlib interactive alteration of line properties

I've been looking for a graphical / ipython console based means to turn lines on and off in a 2D graph generated with matplotlib, but I haven't found anything thus far.
Does anyone know a way to do something like this? What I have in mind specifically is incorporated in MATLAB, and can be seen here:
http://matlab.izmiran.ru/help/techdoc/creating_plots/plot_to5.html
All of the check boxes in the plot browser window will turn the lines on and off; their properties can also be altered graphically in another dialogue box. For now, I've been clicking on the properties button, and setting linetype to none, but this is cumbersome for a graph with many lines...
Thanks Vadim for your answer - you're right that the widgets provide an example with this functionality - to an extent. The example you provide doesn't give the graphical feedback I had in mind; instead, the widgets example closest to my request is actually check_buttons.py (see: http://matplotlib.org/examples/widgets/check_buttons.html)
Here, a side-box of labelled check buttons can be created, where upon clicking the checked buttons, it will turn the lines on and off - see the figure below. I suppose this could be built up into something along the lines of a plot browser like in matlab, but would require additional work to incorporate simple changes to the line style, etc.
I am still interested to know if someone has already done all of the work in making such functionality available; if not, I will post my best attempt when I get around to it.
plot_browser
I don't have sufficient rep points to add the image inline; my apologies.
Yes, there exists module named matplotlib.widgets. There are some example here. It allows you to do exactly what you asked for (source):

Python hide already printed text

I'm creating a simple two-player board game where each player must place pieces on their own boards. What I would like to do is by either:
opening a new terminal window (regardless which OS the program is run on) for both players so that the board is saved within a variable but the other player cannot scroll up to see where they placed their pieces.
clearing the current terminal completely so that neither player could scroll and see the other player's board. I am aware of the unix 'clear' command but it doesn't achieve the effect I'm after and doesn't work with all OS's (though this might be something that I'll have to sacrifice to get a working solution)
I have tried clearing the screen but haven't been able to completely remove all the text. I don't have a preference; whichever method is easier. Also, if it would be easier to use a different method that I haven't thought of, all other suggestions are welcome. Thanks in advance!
EDIT: Other solutions give the appearance that text has been cleared but a user could still scroll up and see the text that was cleared. I'd like a way to remove any way that a user could see this text.
EDIT 2: Please read the other answers and the comments as they provide a lot of information about the topic as a whole. In particular, thanks to #zondo.
Consider using a portable terminal handling library. They abstract away the system specifica of common tasks like erasing the "screen" (i.e. terminal), or placing output at a specific position on the "screen" (again, meaning the text terminal). However, to use such a library effectively, you often have to switch to its style of generating output on the screen instead of naively printing strings.
curses is one such library (based on the C library ncurses) and included in the Python standard library. To get started, be sure to have a look at the curses tutorial in the official Python documentation.
I'd personally just use this.
import os
os.system("cls" if os.name == "nt" else "clear") #"cls" for Windows, otherwise "clear"
I would recomend a simple ANSI escape code to move the cursor position, Cursor Escape Codes, to the start of the board everytime. There is also an ANSI escape code that completly clears the console though, so you can choose.
If you are on windows you must first import colorama a module that makes windows prompt be able to use the ANSI codes as such:
import colorama # OR: from colorama import init
colorama.init() # AND THEN: init()
So if your board has n rows, after the user input for their turn, you move the cursor UP n rows + however many were required for user input, so if you wrote Input row, col: ... then you would go UP n+1, etc...
A simple example:
numLines = 1
print("Hello world!")
print("\033[<{0}>A".format(numLines), "This came AFTER hello world line")
You may not like this, it's a bit higher level than a basic two player board game, but there is always using some sort of GUI.
I personally like tkinter myself.
You don't want the option of people scrolling up to see printed text, but you can't remove what has been printed, that's like asking a printer to remove ink off a page. It's going to stay there.
Research a GUI interface, and try and make the game in that. Otherwise, you could let me take a stab at creating a explanatory piece of code that shows you how to use tkinter. If you do, link me the game you have so I can understand what you want.

How to make PowerBuilder UI testing application?

I'm not familiar with PowerBuilder but I have a task to create Automatic UI Test Application for PB. We've decided to do it in Python with pywinauto and iaccesible libraries. The problem is that some UI elements like newly added lists record can not be accesed from it (even inspect32 can't get it).
Any ideas how to reach this elements and make them testable?
I'm experimenting with code for a tool for automating PowerBuilder-based GUIs as well. From what I can see, your best bet would be to use the PowerBuilder Native Interface (PBNI), and call PowerScript code from within your NVO.
If you like, feel free to send me an email (see my profile for my email address), I'd be interested in exchanging ideas about how to do this.
I didn't use PowerBuilder for a while but I guess that the problem that you are trying to solve is similar to the one I am trying to address for people making projects with SCADA systems like Wonderware Intouch.
The problem with such an application is that there is no API to get or set the value of a control. So a pywinauto approach can't work.
I've made a small tool to simulate the user events and to get the results from a screencapture. I am usig PIL and pytesser ORM for the analysis of the screen captures. It is not the easiest way but it works OK.
The tool is open-source and free of charge and can be downloaded from my website (Sorry in french). You just need an account but it's free as well. Just ask.
If you can read french, here is one article about testing Intouch-based applications
Sorry for the self promotion, but I was facing a similar problem with no solution so I've written my own. Anyway, that's free and open-source...
I've seen in AutomatedQa support that they a recipe recommending using msaa and setting some properties on the controls. I do not know if it works.
If you are testing DataWindows (the class is pbdwxxx, e.g. pbdw110) you will have to use a combination of clicking at specific coordinates and sending Tab keys to get to the control you want. Of course you can also send up and down arrow keys to move among rows. The easiest thing to do is to start with a normal control like an SLE and tab into the DataWindow. The problem is that the DataWindow is essentially just an image. There is no control for a given field until you move the focus there by clicking or tabbing. I've also found that the DataWindow's iAccessible interface is a bit strange. If you ask the DataWindow for the object with focus, you don't get the right answer. If you enumerate through all of the children you can find the one that has focus. If you can modify the source I also advise that you set AccessibleName for your DataWindow controls, otherwise you probably won't be able to identify the controls except by position (by DataWindow controls I mean the ones inside the DataWindow, not the DataWindow itself). If it's an MDI application, you may also find it useful to locate the MicroHelp window (class fnhelpxxx, e.g. fnhelp110, find from the main application window) to help determine your current context.
Edited to add:
Sikuli looks very promising for testing PowerBuilder. It works by recognizing objects on the screen from a saved fragment of screenshot. That is, you take a screenshot of the part of the screen you want it to find.

Categories