(python) How to create static text in curses - python

I am creating a text adventure. How could I to add static text to this.
What i mean is some text that always stays on the left side of the window. Even if all the other text is scrolling down. Also how could i make this text red.

Here is an example that shows some static text in red(that always stays on top):
import sys
import curses
curses.initscr()
if not curses.has_colors():
curses.endwin()
print "no colors"
sys.exit()
else:
curses.start_color()
curses.noecho() # don't echo the keys on the screen
curses.cbreak() # don't wait enter for input
curses.curs_set(0) # don't show cursor.
RED_TEXT = 1
curses.init_pair(RED_TEXT, curses.COLOR_RED, curses.COLOR_BLACK)
window = curses.newwin(20, 20, 0, 0)
window.box()
staticwin = curses.newwin(5, 10, 1, 1)
staticwin.box()
staticwin.addstr(1, 1, "test", curses.color_pair(RED_TEXT))
cur_x = 10
cur_y = 10
while True:
window.addch(cur_y, cur_x, '#')
window.refresh()
staticwin.box()
staticwin.refresh()
inchar = window.getch()
window.addch(cur_y, cur_x, ' ')
# W,A,S,D used to move around the #
if inchar == ord('w'):
cur_y -= 1
elif inchar == ord('a'):
cur_x -= 1
elif inchar == ord('d'):
cur_x += 1
elif inchar == ord('s'):
cur_y += 1
elif inchar == ord('q'):
break
curses.endwin()
A screenshot of the result:
Remember that windows on top must be refresh()ed last otherwise the windows that should go below are drawn over them.
If you want to change the static text do:
staticwin.clear() #clean the window
staticwin.addstr(1, 1, "insert-text-here", curses.color_pair(RED_TEXT))
staticwin.box() #re-draw the box
staticwin.refresh()
Where the 1, 1 means to start writing from the second character of the second line(remember: coordinates start at 0). This is needed since the window's box is drawn on the first line and first column.

You create static text by putting it in a separate window. Create a window large enough for all the text, and then create a smaller window for the dynamic text. Text is colored by passing the various COLOR_* constants as the text attribute.

Related

python keyboard wont stop once key is pressed

I have an endless loop in MAIN and ive looked at it so many times.
def click(x,y):
win32api.SetCursorPos((x,y))
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0)
time.sleep(0.05)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0)
def click_x_box(Box_x_axis, X_axis, Y_Axis_top, Y_Axis_bottom):
#[Check if pixel is RED from top]
while pyautogui.pixel(X_axis, Y_Axis_top)[0] == 255 and pyautogui.pixel(X_axis, Y_Axis_top)[1] != 255:
# click function has no loops
click(Box_x_axis, Y_Axis_top)
Y_Axis_top += 19
print("finished top-down loop")
#[Check if pixel is RED from bottom]
while pyautogui.pixel(X_axis, Y_Axis_bottom)[0] == 255 and pyautogui.pixel(X_axis, Y_Axis_bottom)[1] != 255:
click(Box_x_axis, Y_Axis_bottom)
Y_Axis_bottom -= 19
print("finished bottom-up loop")
After I press 'q' once the "keyboard.is_pressed" line will keep re-going through, I dont know why it keeps getting through if 'q' is not being held down?
def main():
# Continue unticking boxes while 'q' is held
print("Hold 'q' to start clearing out the page of red")
while True:
if keyboard.is_pressed("q") == True:
print("q is pressed")
click_x_box(Box_x_axis, X_axis, Y_Axis_top, Y_Axis_bottom)
if __name__ == "__main__":
main()
EDIT
Ive figured out that when for whatever reason the click function is still engaging despite there being no 255,0,0 (red) on screen...

Windows updating breaks drawing on them with Python Xlib

I'm trying to write a fun project for myself, which is a screenshot tool written in Python. I've run into an issue with one part of this, which is that I want to draw a rectangle on the screen, get the coordinates, then take a screenshot of this region. I have this working for the most part, but when the window underneath the selection updates, it breaks the drawing of the rectangle.
Here is a video displaying the issue: https://gfycat.com/EmotionalThankfulFlycatcher
I've tried reading the Xlib documentation to see if there's a way I can comfortably handle this, but wasn't able to find anything. Another alternative I could try would be to take a screenshot of the entire screen, and then take a selection of that instead of taking a region of the live desktop.
Is there anyway I can handle this, without going the route of taking a screenshot of the entire desktop and cropping that?
import sys
from Xlib import X, display, Xutil, xobject, Xcursorfont
class xselect:
def __init__(self):
# X display
self.d = display.Display()
# Screen
self.screen = self.d.screen()
# Draw on the root window (desktop surface)
self.window = self.screen.root
def select_region(self):
# Set cursor to crosshair
font = self.d.open_font('cursor')
cursor = font.create_glyph_cursor(font, Xcursorfont.crosshair,
Xcursorfont.crosshair+1,
(65535, 65535, 65535), (0, 0, 0))
self.window.grab_pointer(1, X.PointerMotionMask|X.ButtonReleaseMask|X.ButtonPressMask,
X.GrabModeAsync, X.GrabModeAsync, X.NONE, cursor, X.CurrentTime)
colormap = self.screen.default_colormap
color = colormap.alloc_color(0, 0, 0)
# Xor it because we'll draw with X.GXxor function
xor_color = color.pixel ^ 0xffffff
self.gc = self.window.create_gc(
line_width = 1,
line_style = X.LineSolid,
fill_style = X.FillOpaqueStippled,
fill_rule = X.WindingRule,
cap_style = X.CapButt,
join_style = X.JoinMiter,
foreground = xor_color,
background = self.screen.black_pixel,
function = X.GXxor,
graphics_exposures = False,
subwindow_mode = X.IncludeInferiors,
)
done = False
started = False
start = dict(x=0, y=0)
end = dict(x=0, y=0)
last = None
while not done:
e = self.d.next_event()
# Window has been destroyed, quit
if e.type == X.DestroyNotify:
sys.exit(0)
# Mouse button press
elif e.type == X.ButtonPress:
# Left mouse button?
if e.detail == 1:
start = dict(x=e.root_x, y=e.root_y)
started = True
# Right mouse button?
elif e.detail == 3:
sys.exit(0)
# Mouse button release
elif e.type == X.ButtonRelease:
end = dict(x=e.root_x, y=e.root_y)
if last:
self.draw_rectangle(start, last)
done = True
pass
# Mouse movement
elif e.type == X.MotionNotify and started:
if last:
self.draw_rectangle(start, last)
last = None
last = dict(x=e.root_x, y=e.root_y)
self.draw_rectangle(start, last)
pass
# Keyboard key
elif e.type == X.KeyPress:
sys.exit(0)
elif e.type == X.EnterNotify:
print(' EnterNotify')
self.d.ungrab_pointer(0)
self.d.flush()
coords = self.get_coords(start, end)
if coords['width'] <= 1 or coords['height'] <= 1:
sys.exit(0)
else:
return coords
def get_coords(self, start, end):
safe_start = dict(x=0, y=0)
safe_end = dict(x=0, y=0)
if start['x'] > end['x']:
safe_start['x'] = end['x']
safe_end['x'] = start['x']
else:
safe_start['x'] = start['x']
safe_end['x'] = end['x']
if start['y'] > end['y']:
safe_start['y'] = end['y']
safe_end['y'] = start['y']
else:
safe_start['y'] = start['y']
safe_end['y'] = end['y']
return {
'start': {
'x': safe_start['x'],
'y': safe_start['y'],
},
'end': {
'x': safe_end['x'],
'y': safe_end['y'],
},
'width' : safe_end['x'] - safe_start['x'],
'height': safe_end['y'] - safe_start['y'],
}
def draw_rectangle(self, start, end):
coords = self.get_coords(start, end)
self.window.rectangle(
self.gc,
coords['start']['x'],
coords['start']['y'],
coords['end']['x'] - coords['start']['x'],
coords['end']['y'] - coords['start']['y']
)
I'm still new to X11 myself, but the X11 tag on stackoverflow is pretty much dead so I'll try to answer anyway.
For taking screenshots, look at this. You want to use XGetImage, which allows you to specify the rectangle you want.
Now for drawing the rectangle, as far as I know drawing on the root window can be pretty iffy. You could instead create a fullscreen window with a transparent background. This would also allow you to give the area around the rectangle a darker tint, for example.

How to allow caps in this input box program for pygame?

I found this input box module on the internet but it only allows lower case no upper. So could someone tell me what to change in the module to allow caps as im creating a small multiplayer game and i need login system and chatbox.
Here is the code example I am working with
# by Timothy Downs, inputbox written for my map editor
# This program needs a little cleaning up
# It ignores the shift key
# And, for reasons of my own, this program converts "-" to "_"
# A program to get user input, allowing backspace etc
# shown in a box in the middle of the screen
# Called by:
# import inputbox
# answer = inputbox.ask(screen, "Your name")
#
# Only near the center of the screen is blitted to
import pygame, pygame.font, pygame.event, pygame.draw, string
from pygame.locals import *
def get_key():
while 1:
event = pygame.event.poll()
if event.type == KEYDOWN:
return event.key
else:
pass
def display_box(screen, message):
"Print a message in a box in the middle of the screen"
fontobject = pygame.font.Font(None,18)
pygame.draw.rect(screen, (0,0,0),
((screen.get_width() / 2) - 100,
(screen.get_height() / 2) - 10,
200,20), 0)
pygame.draw.rect(screen, (255,255,255),
((screen.get_width() / 2) - 102,
(screen.get_height() / 2) - 12,
204,24), 1)
if len(message) != 0:
screen.blit(fontobject.render(message, 1, (255,255,255)),
((screen.get_width() / 2) - 100, (screen.get_height() / 2) - 10))
pygame.display.flip()
def ask(screen, question):
"ask(screen, question) -> answer"
pygame.font.init()
current_string = []
display_box(screen, question + ": " + string.join(current_string,""))
while 1:
inkey = get_key()
if inkey == K_BACKSPACE:
current_string = current_string[0:-1]
elif inkey == K_RETURN:
break
elif inkey == K_MINUS:
current_string.append("_")
elif inkey <= 127:
current_string.append(chr(inkey))
display_box(screen, question + ": " + string.join(current_string,""))
return string.join(current_string,"")
def main():
screen = pygame.display.set_mode((320,240))
print ask(screen, "Name") + " was entered"
if __name__ == '__main__': main()
Thx!
If you change the corresponding code to:
elif inkey <= 127:
if pygame.key.get_mods() & KMOD_SHIFT or pygame.key.get_mods() & KMOD_CAPS: # if shift is pressed or caps is on
current_string.append(chr(inkey).upper()) # make string uppercase
else:
current_string.append(chr(inkey)) # else input is lower
That should work.
If you want more info on keyboard modifier states look here

msvcrt getch pauses script, has to continue

PYTHON 3.3, msvcrt
import sys, msvcrt
print("Please press a key to see its value")
while 1:
key = msvcrt.getch()
print("the key is")
print(key)
if ord(key) == 27: # key nr 27 is escape
sys.exit()
this is my code, just as an example.
the code pauses when it gets to the key = msvcrt.getch()*, or *key = ord(getch()) for that matter, right here i used the first one.
I'd like to have this code constantly print the key is
instead of just printing the key is when i give a new input (when i press a key).
so the printed output would look something like this:
the key is
the key is
the key is
the key is
the key is
the key is
77
the key is
the key is
the key is
which is needed if you want to make something like snake, where you don't want your game to be paused everytime you want to getch, you don't want it to pause, waiting for an input.
Use msvcrt.kbhit to check whether key was pressed:
import sys, msvcrt
import time
print("Please press a key to see its value")
while 1:
print("the key is")
if msvcrt.kbhit(): # <--------
key = msvcrt.getch()
print(key)
if ord(key) == 27:
sys.exit()
time.sleep(0.1)
Another example to make Python program stop at a certain level, and wait for the user to press Enter "Yes" and/ or Space for "No" can be generated using pygame.
As an example I used Space for "No", but you could use the touche Escape for "No".
You might not need some imported librairies. Needed them while making tic toc toe game.
The code is below :
import numpy as np
import pygame as pg
from math import floor
import sys
import time
pg.init()
black = (0, 0, 0)
red = (255, 0, 0)
blue = (0, 0, 255)
yellow = (255, 255, 0)
white = (255, 255, 255)
gris = (192, 192, 192)
cell = 100
thickness =2
window = pg.display.set_mode((300, 300))
pg.display.set_caption("by #djilytech")
for col in range(3):
for row in range(3):
pg.draw.rect(window, gris, (row * cell, col * cell, cell - 2, cell - 2), thickness)
pg.time.delay(120)
pg.display.update()
run = False
while not run:
for ev in pg.event.get():
if ev.type == pg.QUIT:
pg.quit()
sys.exit()
if ev.type == pg.KEYDOWN:
if ev.key == pg.K_RETURN:
print(" This mean the user wants to play again or said YES")
# So I can have some code here for what I want
if ev.key == pg.K_SPACE:
print("User does not want to continue")
# Will exit the program
run = True

Pygame and Livewires button press not working?

so in my menu in a game I'm creating a picture is displayed which shows how to play the game, and I have some code so that when the player presses the b button it returns to the main menu, but this doesn't work, can someone help me please?
def manual():
image = games.load_image("options.jpg")
games.screen.background = image
if games.keyboard.is_pressed(games.K_b):
menu()
games.screen.mainloop()
the 'menu()' is another function which has all the main menu code in it
Here is the menu function
def menu():
pygame.init()
menubg = games.load_image("menubg.jpg", transparent = False)
games.screen.background = menubg
# Just a few static variables
red = 255, 0, 0
green = 0,255, 0
blue = 0, 0,255
size = width, height = 640,480
screen = pygame.display.set_mode(size)
games.screen.background = menubg
pygame.display.update()
pygame.key.set_repeat(500,30)
choose = dm.dumbmenu(screen, [
'Start Game',
'Manual',
'Show Highscore',
'Quit Game'], 220,150,None,32,1.4,green,red)
if choose == 0:
main()
elif choose == 1:
manual()
elif choose == 2:
print("yay")
elif choose == 3:
print ("You choose Quit Game.")
I think is_pressed() in manual() doesn't wait for your press so you call mainloop() so I think you never leave that loop.
I see other bad ideas in your code like:
menu() call manual() which call menu() which call manual() etc. - use return and use loop in menu()
every time you call menu() you call pygame.init() and pygame.display.set_mode() - you should use it only once.
EDIT:
I don't know how games.keyboard.is_pressed() works (because there is no that function in PyGame) but I think manual() could be:
def manual():
image = games.load_image("options.jpg")
games.screen.background = image
while not games.keyboard.is_pressed(games.K_b):
pass # do nothing
# if `B` was pressed so now function will return to menu()
and you have to create loop in menu:
running = True
while running:
choose = dm.dumbmenu(screen, [
'Start Game',
'Manual',
'Show Highscore',
'Quit Game'], 220,150,None,32,1.4,green,red)
if choose == 0:
main()
elif choose == 1:
manual()
# if 'B' was press manual() will return to this place
elif choose == 2:
print("yay")
elif choose == 3:
running = False
print ("You choose Quit Game.")

Categories

Resources