I have two modules one for the Main Menu lets call it MainMenu.py and another one for the game InGame.py, there is a button in each module that when clicked should take me to the other module:
NOTE: I always run MainMenu.py first then i open InGame using the button, I just need a way to go back to MainMenu.py then again back to a new ran InGame, I tried using classes for both modules but It didnt work because i have circular dependencies between other modules and InGame.py
# MainMenu.py
if button_clicked:
# run InGame.py
and
# InGame.py
if button_clicked:
#run MainMenu.py
I tried directly importing each module at first which obviously didnt work, it would take me from MainMenu to InGame, back to MainMenu and stops there, pressing the button in MainMenu wont do anything.
then I tried:
# MainMenu.py
if button_clicked:
if __name__ == "main":
import InGame
else:
del InGame
sys.modules.pop('InGame')
import InGame
and
# InGame.py
if button_clicked:
import MainMenu
But it also did nothing after going to MainMenu and trying to press the button to InGame, it just stops there.
I am sure this means my design is a mess but I even tried changing the whole design with no success so im looking for an easier fix.
I believe what you are trying to do is discouraged, there are a number of alternative approaches you can take which will remove the need for such cyclic references. The first immediate idea I have to solve your problem involves using an event driven design pattern. The general concept behind it is to have the MainMenu register an event that is called by your button. Your button does not need to know who is listening to the event but the main menu can still just as easily receive the message.
EDIT: The name was eluding me whilst typing the answer, its typically called the Observer Pattern.
When you run into problems like these, it generally indicates bad design, Its good that you were able to recognise that its a bit messy. I highly suggest looking into design patterns (if you dont know them already) even if they are in languages you dont know since the concept behind them is whats important.
In your case having something which mediates the flow between the two modules is the way to go, it will act as a parent in a sense and let you go between the two children
Related
Apologies if this is a completely easy fix and I've just missed it. I am learning Python and I am trying to develop a GUI alongside my backend code using Tkinter. This is completely foreign to me and I have recently come across the problem that when I press my buttons there is a very small chance that it will make my window move behind all other open programs.
I am not entirely sure what is causing this but my guess is it stems somehow from one of two functions I have; one meant to minimise the main root window and the second to reveal it. However, these functions are not called in any place in my program that I would not expect them and the windows being minimised are not the root window (which my two functions act on).
I have both functions added below (hopefully, I am pretty new to SO) but if any additional code is needed I will supply it. I have quite a bit of code and everything else functions perfectly so I didn't want to post all my code is all.
There is no particular combination of button presses or buttons in particular which cause it, it appears to be any of them seemingly at random. It sends whatever window I have up to the taskbar.
def revealMenu():
root.update()
root.deiconify()
def hideMenu():
root.withdraw()
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.
I'll preface this by saying that I'm very inexperienced with python, and I'm hoping that means the solution to my problem will be simple.
My program will be performing simple actions in another window, so ideally I would like my script to make sure that this other window is maximized and active before it proceeds with the rest of the commands. This has proved to be much more difficult than I had expected.
I am fairly certain that I can achieve this with win32gui using find_window and setting it to the foreground. I thought I had found my solution when I came across this previous question:
Python Window Activation
Unfortunately I was unable to use the solution code or manipulate it to solve my problem for a few reasons:
-The way that user had defined find_window only allows you to choose by the classname of the window, which I don't know and haven't been able to find since it is just a game running in Java. I couldn't seem to change that line to work for the specific windowname (Which I do know) as it is not the "default argument".
-I don't want to enumerate the windows to find it as I'm not sure how that would work.
-using find_window_wildcard as it's written in that script has managed to bring the window to the foreground a few times, but only if the window was already open, and it only works intermittently.
-set_foreground() requires one input statement and no matter how I try to set it I am always given an error that I either have the wrong number of elements or an invalid handle on the window.
I know that I'm stupid; but a clear and concise solution to this problem or at least a good explanation of the find_window/getwindow syntax would be a godsend to myself and anyone else who's having this problem.
I would strongly suggest you take a look at the pages for Swapy and for pywinauto. They can help you do some awesome things when it comes to UI Automation.
The way that user had defined find_window only allows you to choose by the classname of the window
The way the user defined it is to pass the two parameters class_name and window_name through, untouched, to win32gui.FindWindow (which in turn just calls the Win32 API function FindWindow). So, just do this:
windowmgr.find_window(None, 'My Window Name')
But even if that weren't true, you don't need to use his find_window function; it should be pretty obvious how to call win32gui.FindWindow yourself:
hwnd = win32gui.FindWindow(None, 'My Window Name')
And if you want a good explanation of the FindWindow/EnumWindows/etc. syntax, did you try looking at the docs for them? Is there something you didn't understand there?
Meanwhile:
… the classname of the window, which I don't know and haven't been able to find since it is just a game running in Java
What difference does it make that it's running in Java? You can enumerate the windows and print out their classnames, whether they're written in C++, Java, .NET, Python, or anything else. Or use one of the tools that comes with Visual Studio/VS Express, or any of the free improved versions you can find all over the net, like MS Spy++, which will let you point at a window and give you the caption and class name.
I don't want to enumerate the windows to find it as I'm not sure how that would work.
Just call windowmgr.find_window_wildcard(wildcard) with a regular expression, and it'll enumerate the windows and compare their titles to that regular expression.
If you want to write your own code to do it, just write a function like this:
def my_callback(hwnd, cookie):
Now, when you do this:
win32gui.EnumWindows(my_callback, some_cookie)
… it will call your my_callback function once per window, with hwnd being the window (which you can pass to win32gui functions like, e.g., GetWindowText), and cookie being the same some_cookie value you passed in. (If you don't need anything passed in, just pass None, and don't do anything with the value in your callback function. But you can see how the other answerer used it to pass the regular expression through.)
Meanwhile:
using find_window_wildcard as it's written in that script has managed to bring the window to the foreground a few times, but only if the window was already open, and it only works intermittently.
First, you can't bring a window to the foreground if it doesn't exist. How do you expect that to work?
As far as working intermittently, my guess is that there are lots of windows that match your wildcard, and the program is going to just pick one of them arbitrarily. It may not be the one you want. (It may even be a hidden window or something, so you won't see anything happen at all.)
At any rate, you don't need to use find_window_wildcard; if you know the exact name, use that. Of course it still may not be unique (whatever the game's name is, there's nothing stopping you from opening an email message or a Notepad window with the same title… which, by the way, is why you want to try class names first), but at least it's more likely to be unique than some underspecified wildcard.
So, what if the class name isn't unique (or, even worse, it's one of the special "number" classes, like #32770 for a general dialog window), and neither is the window name? You may be able to narrow things down a little better by looking at, say, the owning process or module (exe/dll), or the parent window, or whatever. You'll have to look through the win32gui and/or MSDN docs (linked above) for likely things to try, and play around through trial and error (remember the Spy tool, too) until you find some way to specify the window uniquely. Then code that up.
I've created a simple console based Scrabble game using Python. I tried to encapsulate the game model from the I/O as much as possible, meaning I created a few classes to describe the game with its rules and the current state. Basically I came up with these classes:
LetterSet: To describe the tiles in the game (score, total amount, etc.)
Board: A representation of the Board with its tiles and auxiliry functions
Player: A virtual class to subclass real Classes like Human or Bot, got one method play() which should return the players move
Game: Well ...
Everything works fine using a simple linear and synchronous flow with my console app.
But it turns out that its not that easy to port this concept to Qt. I've created all neccessary widgets like a Dragable board, general visual elements describing the game state and simple buttons like 'Pass', 'Continue', 'Exchange'.
The problem is, that I'm not sure how to handle the play() method which may use the Qt interface I created to generate a valid move. That's no problem for the Bot though, which simply searches a move without any interaction.
My current idea is to create a local event loop like described here and to wait for the buttons to get clicked in my play() method defined in Human(Bot). This is kinda ugly so I'm wondering if there is a better way to do it.
I would like the main logic to be the same e.g. the Player class serves a play() method which generates a move and returns it. This way it should be possible to create any type of Player's, like network players or bots. This synchronous way of doing it doesn't work very well with Qt's based signal/slot way of doing things. Hope someone got a neat idea to solve my problem.
Summarized: How to generate the Player's move inside its play() method and returning it like a simple move = player.play(game) call?
Edit: A snapshot to get an idea of what I'm talking about:
(source: b52 at reaktor42.de)
Edit2: This is rather old and I completed the assignment about two years ago successfully. Nevertheless I thought it might be useful for others if I publish the results through github.
Thanks in advance, Oli
What you can do in the Player play function is:
Enabled the buttons and connect them to slots (one per action)
Wait until the player move is validate (or any other reason to quit)
Disconnect signals to slot when the player move has been received (or is validated)
This is one way but you should modify it to fit your game model
My current idea is to create a local event loop like described here and to wait for the buttons to get clicked in my play() method defined in Human(Bot). This is kinda ugly so I'm wondering if there is a better way to do it.
I don't see why you think this is ugly. This is how practically any GUI program works: initialise a set of controls (buttons, etc), wait for the user to interact with the controls, respond to the interaction, and repeat.
I'd recommend you have a button for the player to submit their move. They click that, an event fires, the event handler tells your Player object that a move has been made and it passes it to the game logic event handler. The game logic checks whether the move is legal (you should put the code here rather than in the GUI classes), and passes control to the next Player object if the move was legal.
I think you're right that there's a bit of a disconnect between the event based model in a GUI environment and your original application design. With a console app you write the event loop, but in a GUI app in any of the frameworks I know, the framework has one of it's own.
I'd have the Player object send it's move via a signal to the game object. You would need to structure your base Player class around this design. It shouldn't all that hard to do as you've already got the actual logic worked out, you're just re-wiring it a bit.
Note that your Player objects are actually just interfaces between the game and the actual player which might be someone clicking buttons in the UI, or a remote player over a network connection. Only in the case of a bot can the player object actually be the player, and even in that case you might be best off having separate strategy engine objects. Thinking about it that way might help get a grip on the design.
You don't have to do it that way. You can work around it e.g. by the method you describe, but I wouldn't want to mess around with my own event loops inside an application that has it's own GUI event loop. That's fighting against the GUI framework rather than working with it. It's not just Qt that's like this, you'd have an issue similar to this in any GUI framework. It's a different way to think about structuring an application and I'd recommend embracing it.
I've done a few searches but I couldn't find anything about this topic. Perhaps because it is common programmer knowledge (I'm not a programmer, I've learned from necessity), or because I'm going about it the wrong way.
I would like ideas/suggestions on how to manage button states for a GUI. For example, if I have a program which allows the user to import and process data, then certain functions should be inaccessible until the data has been imported successfully, or if they want to graph certain data, they need to select which data to graph before hitting the 'graph' or 'export' button. Even in the simple programs I've built these relationships seems to get complicated quickly. It seems simple to say "User shouldn't be able to hit button 'A' until 'B' and 'C' have been completed, then 'A' should be disabled if button 'D' or the 'Cancel' button. But that's a lot to track for one button. Thus far, I've tried two things:
Changing/Checking button states in the callback functions for the button. So in the above example, I would have code in buttons B's and C's callback to check if A should be enabled. And in buttons D's and Cancel's callbacks I would have code to disable button A. This gets complicated quickly and is difficult to maintain as code changes.
Setting boolean variables in every buttons callback (or just checking the states later using cget()) and checking the variables in a polling function to determine which buttons should be enabled or disabled.
I'm just not sure about this. I would like to make code as short and easy to understand as possible (and easy to edit later), but I don't like the idea of polling all the button states every few hundred milliseconds just for button 'management'. You can extend the same idea to check boxes, menu items, etc... but I'd like to here what others have done and why they do it the way they do.
You are only changing button states based on events, right? There is no reason to 'poll' to see if a button state has changed. What you can do is build a function which does all of the calling for you, then call it with something like disable_buttons([okButton, graphButton, printButton]). When an event takes place that modifies the appropriate user interface options (such as importing data), have another function that turns them on: enable_buttons([graphButton]). You could do this with each object's methods, of course, but making a wrapper allows you to be consistent throughout your application.