I'm making a text adventure, and I want to have pyGame animations and illustrations and a HUD!
How can I insert this console?
Thanks!
I'm pretty sure that's impossible. If you want a console within a Pygame screen then you'll have to write your own, or find one written by someone else (e.g. http://pygame.org/project-pygame-console-287-.html)
For your game, you can use subsurface, for the different screen 'sections'.
Using python 3x will have issues with multiple libraries, that are not precompiled for you. If you can, it will simplify things to Use 2.7 or 2.6. (There is a python2.7 binary, but not on the front page)
A console isn't too hard. You need to break down the components, deciding what you need.
Start with a miniproject, implementing features one at a time.
keyboard input, print letters to console
render text from a string
blit cached text. will have demo code later, if you are interested
dict() of strings, for commands, with values of function names.
draw the last 10 lines of text
up = scroll through command history
allow command aliases, like "n" and "north" will point to move_north
Implement this using a class: Command() . Which stores a list of all aliases.
commands = { "n" : move_north, "s" : move_south, "fps" : toggle_fps, "help" : print_help }
On enter, call the dict's value, if key exists:
if cmd in commands:
commands[cmd]()
# same as commands["n"]()
You could even have the console's print_help() use the function docstrings.
Related
I want to know how to refresh the console of my program as if it was just started. Let's say that my code consists of an infinite loop and it has multiple instances of the print() function within itself, I want, every time that loops returns to its start, all the new data whether there is some change or not to get outputted on the same place of the data that has been outputted the last time.
I have been reading about similar problems others have posted and the answers usually revolve around the idea of using \r, when I do that, however, it's always messy and the strings are either printed halfway or there are missing characters. On Replit there is a module called "replit" and there is a function there called clear() that basically performs what I need, but I don't seem to find it when I am using PyCharm, which means that it is perhaps something that works exclusively within the Replit environment. So I am asking, is there something similar in the standard python library that I can use? Thanks
You can use:
import os
command = 'cls' #for windows
os.system(command)
example:
print('hi')
os.system(command)
print('hi')
Output:
hi
For windows you need:
command = 'cls'
For all others it is:
command = 'clear'
To account for any OS you could use:
import os
def clearConsole():
command = 'clear'
if os.name in ('nt', 'dos'): # If computer is running windows use cls
command = 'cls'
os.system(command)
clearConsole()
There is nothing standard in Python to do it, because Python is not aware of whatever console you are using.
When you call print it is actually writing to a file called "standard output".
It can go to a console if you are running your program in a console (like windows cmd, Linux or Mac OS terminal app, or whatever PyCharm uses).
But it can also be redirected to a regular file by the user of your program.
So there is no standard way.
\r is "carriage return" character. On consoles that respect it, it will set your output position to the beginning of the current line, but will not erase any text already printed on that line (usually).
One way to print text in specific places on the screen is PyCurses.
It supports many consoles and figures out which one you are using automatically.
You can do something like this:
import curses
stdscr = curses.initscr()
stdscr.addstr(x, y, "my string")
By using the addstr isntead of print, you can choose the exact position the text will appear, with X and Y coordinates (first two parameters).
Read the documentation for more ways to manipulate text display with this library.
Is it possible to change the way PyCharm adds the hash # when using the keyboard shortcut to comment a line? (default CTRL+/)
I'd like the # to be at column 1 rather than at the indent level. Also, the cursor is moved down a line after the keyboard shortcut and I'd rather it stay on the same line.
Currently:
def foo():
my_uncommented_line
# commented_with_keyboard_shortcut
var = "and now the cursor is at the start of this line"
What I'd like:
def foo():
my_uncommented_line
# commented_with_keyboard_shortcut
var = "cursor stays on the previous line"
I'm currently searching around the JetBrains plugin repo for something that does this, but no luck thus far.
I know that this doesn't follow PEP8. I'd like to be able to make this change so that I can be consistent with the rest of the project:
Some other good reasons to ignore a particular guideline:
2. To be consistent with surrounding code that also breaks [the guideline].
The most you can do is alter the style:
Given a string, I'd like to be able to send a set of keystrokes to type that string and I'd like to be able to do it in python on OSX (in python because it's part of a larger project already written in python, on OSX because I am trying to port it to OSX).
I'm able to do this now using pyobj like so (this is somewhat simplified):
from Quartz import *
CHAR_TO_SEQUENCE = {
'a':[(0, True), (0, False)]
}
def send_string(string):
for c in string:
sequence = CHAR_TO_SEQUENCE[c]
for keycode, key_down in sequence:
CGEventPost(kCGSessionEventTap, CGEventCreateKeyboardEvent(None, keycode, key_down))
and I've fleshed out CHAR_TO_SEQUENCE to include most of what I can type on my keyboard, which took a while and was tedious.
The problems with this are:
- It only works while the keyboard has the ANSII standard layout. If someone uses a french keyboard, for example, it will type the wrong things.
- It requires this ridiculous table.
I found this general solution for OSX but couldn't figure out how to apply it to python:
How to convert ASCII character to CGKeyCode?
The API mentioned there doesn't seem to be available via pyobj (or maybe I just couldn't figure out the import path).
I've seen some suggestions to set CGEventKeyboardSetUnicodeString to the desired string and not worry about the keycode. But I wasn't able to figure out how to call CGEventKeyboardSetUnicodeString from python (I can't get the arguments right) and it's not clear that this will work because the documentation says that applications can choose to ignore this in favor of the keycode.
Is there a way to do this in python on OSX?
It looks like the Carbon modules don't wrap the TIS* functions, and neither does anything else.
You could extend PyObjC, but it's much simpler to just build a trivial extension module that wraps the two functions you actually need.
Since it was faster to just do it than to explain how to do it, you can get it from https://github.com/abarnert/pykeycode and just do the usual "python setup.py build_ext --inplace" or "sudo python setup.py install", then look at test.py to see how to use it.
I would like to update a number without changing its placement in the output of a program. How would i go about doing this using only what is included in the standard library for python 2.7.2 ?
For example i want output like:
working on: 9
and change to:
working on: 10
without changing the line that it is displayed on. How would i go about doing this? I would also prefer that you not use cls as to prevent "flashing".
How to do this depends on your terminal type (and possibly on your platform). An easy way that works on many platforms and terminals is to use a \r character to move the cursor back to the beginning of the line:
import time
import sys
for i in range(10):
print "\rworking on:", i,
sys.stdout.flush()
time.sleep(1)
To make the line actually appear, you might need the call to sys.stdout.flush().
There isn't any easy way to do this without resorting to a GUI of some type. The standard way to create a GUI using the terminal is python's curses module. For an explanation of how to use curses in your application see: Curses Programming with Python.
I have a program with a GUI interface whose initial set-up I need to do manually. AutoIt has been superbly helpful for that so far, as it provides very easy ways to work even with complex-to-access GUI objects (drop down lists, appear-on-hover menus, etc.).
However, the script that I'll eventually be needing in order to do the program setup will need to be passed a large array/list of variables - there are a lot of different settings that need to be changed.
I've set up the logic for deciding what these set-up variables will be using a Python script. Now I'm trying to figure out how to get Python and AutoIt to talk to each other.
Calling a custom AutoIt script from the command line using Python is mostly out of the question because of the large number of variables that would need to be passed. Doesn't feel pretty. I could try and have Python write an AutoIt "key file", which AutoIt could then read in order to set its initial variables, but I'd like to make sure I've exhausted all options for Python to work directly with AutoIt first.
To that end, I've been trying to use Python along with the win32com library to interface with AutoIt. Things seem to be working well - as long as I reference windows/menus/objects by their string titles rather than their (memory?) handles. This is problematic, as my set-up scripts might be running in parallel, setting up two or more separate files at the same time. If this is the case, opening up a box with a title string "Open file..." in each file at the same time might confuse things.
The obvious way to get around this in AutoIt is to work with the "handles" of the objects in question, which I believe are memory addresses of some kind, rather than their string titles. I'm guessing these are memory addresses as the AutoIt Window Info tool, when pointed to a particular Window/GUI object option lists a hexadecimal number as the object's handle value.
AutoIt has a suite of functions that get the handles of windows, menus, etc. They are implemented in the AutoIt COM dll, but I've not been able to get them to work in Python. The handle functions return a unicode object in Python, not a hex string as in AutoIt. I think this is the reason why functions which then try to use this "handle" in Python don't work.
Example:
autoIt = win32com.client.Dispatch("AutoItX3.Control")
windowHandle = autoIt.WinGetHandle(knownWindowTitle)
returnedWindowTitle = autoIt.WinGetTitle(windowHandle)
Usually, returnedWindowTitle and knownWindowTitle do not match as returnedWindowTitle always seems to be "0". hat's happening here?
Are there other ways for me to call custom AutoIt functions apart from using win32com, the command line, or using an AutoIt keyfile?
Thanks for your help.
EDIT: I forgot to mention that the unicode strings do in fact match the hexadecimal numbers that I get when I print out the handle variable in AutoIt.
For example, in Python, the handle variable when printed out gives me u'000C0326'. In AutoIt it gives me '0x000C0326'.
EDIT: Some trials based on Mat's suggestions:
In: autoIt = win32com.client.Dispatch("AutoItX3.Control")
In: mainWindowTitle = "Untitled"
In: mainWindowHandle = autoIt.WinGetHandle(mainWindowTitle)
In: mainWindowHandle
Out: u'000204AC'
In: testHandle = int(mainWindowHandle, 16)
In: testHandle
Out: 132268
In: autoIt.WinGetTitle(testHandle)
Out: u'0'
EDIT: I found out the type of the window handle object: it's a Microsoft HWND object. AutoIt has a function that can "convert" a base 16 number into an HWND object (i.e. find the HWND object with that base 16 number memory/handle/etc.). Just my luck that they didn't put that function into AutoItX (the COM dll). So, if I really want to run with this, I'll have to try and figure out how to return whatever object it is that's pointed to by the base 16 address, and then transfer it the right way to AutoItX? I'm probably sounding very confused, because all of this is not super clear in my head right now.
For the sake of search, I'll post the solution that I've found.
Here's the code:
In: autoIt = win32com.client.Dispatch("AutoItX3.Control")
In: autoIt.AutoItSetOption("WinTitleMatchMode", 4)
In: mainWindowTitle = "Untitled"
In: mainWindowHandle = autoIt.WinGetHandle(mainWindowTitle)
In: mainWindowHandle
Out: u'000204AC'
In: testHandle = "[HANDLE:%s]" % mainWindowHandle
In: autoIt.WinGetTitle(testHandle)
Out: u'Untitled - Notepad'
autoIt.AutoItSetOption("WinTitleMatchMode", 4) tells autoit to use advanced title matching, which allows us to specify a window handle with the [HANDLE:000204AC] string.
No need for the actual window handle here.
By the way, I discovered this solution by stumbling on this forum post. I've found that it's often helpful to not restrict my searches to the specific language I'm looking for. Most of the time, a solution can be found in a different language which can be easily ported to the language of your choice.
The type of window handles is string. The reason for that is WinList returns both the window handle and the window title. A title cannot be fit into a handle type, but a handle can be fit into a string type (for title). My guess is that they took that design descision and applied it to other functions as well. If you look at the documentation for WinGetHandle it will tell you the return type for a handle: It's a string.
AutoIt has a function that can "convert" a base 16 number into an HWND object.
Exactly! That's the key. AutoIt does this for you. You're trying to convert the handle into something useful for AutoIt, but AutoIt can already use those handles stored as strings.
Your test should be:
In: autoIt = win32com.client.Dispatch("AutoItX3.Control")
In: mainWindowTitle = "Untitled"
In: mainWindowHandle = autoIt.WinGetHandle(mainWindowTitle)
In: mainWindowHandle
Out: u'000204AC'
In: autoIt.WinGetTitle(mainWindowHandle)
Out: u'Untitled - Notepad'
When you want to use that handle in other libraries, you may run into some problems. I would recommend then that you try to parse the number like you did in your tests, and pass it along. AutoIt is 'smart' enough to figure out what to do in most cases, maybe the library isn't though.