Curses in Python2.7.10 / 3.4.3 addstr() error - python

I am testing out the curses module for python and I encountered this error while trying a simple script:
NameError: global name 'addstr' is not defined
Here is my code:
#!/usr/bin/env python
import curses, sys
from curses import *
def main():
stdscr = initscr()
addstr("Hello")
endwin()
if __name__ == "__main__":
main()
I don't know what Newbie mistake I made, I am following a guide for curses on python.
Thanks in advance.

You need to call addstr() on stdscr, since that is the window object. Here's an example of a curses application:
import curses
import time
stdscr = curses.initscr()
curses.noecho()
curses.cbreak()
stdscr.addstr("Hello World")
stdscr.refresh()
try:
while True:
time.sleep(0.001)
except KeyboardInterrupt:
pass
curses.nocbreak()
curses.echo()
curses.endwin()
Note that the while loop is simply so the curses terminal is displayed until you hit Ctrl-C, otherwise you won't really see much.

Related

Python misinterpret KeyboardInterrupt exception when using Lingoes

I want to write a python program (run.py) that always runs and only stops running when Ctr-C is pressed. This is how I implement it:
wrapper.py:
import subprocess
import signal
def sig_handler(signum, frame):
res = input("Ctrl-c was pressed. Do you really want to exit? y/n ")
if res == 'y':
exit(1)
signal.signal(signal.SIGINT, sig_handler)
while(True):
p = None
p = subprocess.Popen("python run.py", shell=True)
stdout, stderr = p.communicate()
run.py:
print('aaaaa')
print('bbbbb')
However, when I hold left-mouse and select text in the terminal that is running wrapper.py, this event is understood incorrectly as Ctr-C then the wrapper.py stop running run.py. My question is how to prevent reading mouse events as KeyboardInterrupt in python (Unix). Thanks!
Terminal
Instead of using a module like signal to achieve this you could opt to use exceptions since it is a pretty exceptional case that your program will receive a keyboard interrupt.
#!/usr/bin/env python3
import sys
def main() -> int:
try:
while True:
print(sys.argv)
except KeyboardInterrupt as e:
return 0
if __name__ == '__main__':
try:
sys.exit(main())
except Exception as e:
print(f'Error: {e}', file=sys.stderr)
sys.exit(1)
The source code has no problem. The problem is caused by dictionary software. The software has a feature of selecting word to translate. By somehow it converts the mouse event (selecting word) to Ctr-C then the program above exits. When I turn off the dictionary software, the problem disappears. I will close the thread here

Python print messed up after calling curses wrapper

I am having a problem with curses library in Python. Consider the following code:
def main(stdscr):
print('Hello World!!')
create_screen()
curses.endwin()
if __name__ == "__main__":
curses.wrapper(main)
The problem is every text printed by "print" function is messed up even before calling "create_screen()" function which initiates the screen by "curses.initscr()"
You can use print and input normally before and after your program uses curses. Also, you do not have to put all your code into main, and you don't have to pass the main function to curses, either. main is just a function like any other. Check out this simple example:
import curses, time
def incurses(stdscr):
stdscr.addstr(0, 0, "Exiting in ")
stdscr.addstr(2, 0, "Hello World from Curses!")
for i in range(5, -1, -1):
stdscr.addstr(0, 11, str(i))
stdscr.refresh()
time.sleep(1)
curses.endwin()
def main():
print('Hello World!!')
choice = input("Start Curses Program? ")
if choice == "yes":
curses.wrapper(incurses)
print("After curses")
if __name__ == "__main__":
main()
This prints and asks for user input, then shows a curses screen, then goes back into "normal" printing mode.

Unable to remove lockfile

I'm trying to use zc.lockfile. I see that a lockfile is created in the same directory as my python script, but when I press ctrl+C, the file is NOT removed. I have a callback registered and have even tested given a long time (not sure if zc.lockfile spawns a new thread and needed time to complete).
import os
import sys
import signal
import time
import zc.lockfile
program_lock = None
def onExitCodePressed(signal, frame):
"""Callback run on a premature user exit."""
global program_lock
print '\r\nYou pressed Ctrl+C'
program_lock.close()
time.sleep(5)
sys.exit(0)
def main():
signal.signal(signal.SIGINT, onExitCodePressed)
if os.path.exists('myapp_lock'):
print "\nAnother instance of the program is already running.\n"
sys.exit(0)
else:
program_lock = zc.lockfile.LockFile('myapp_lock')
while True:
continue
if __name__ == '__main__':
main()

Can I use Python's curses and cmd libraries together?

In Python, I'd like to write a terminal program using both cmd and curses together, ie. use cmd to accept and decode full input lines, but position the output with curses.
Mashing together examples of both curses and cmd like this :
import curses
import cmd
class HelloWorld(cmd.Cmd):
"""Simple command processor example."""
def do_greet(self, line):
screen.clear()
screen.addstr(1,1,"hello "+line)
screen.addstr(0,1,">")
screen.refresh()
def do_q(self, line):
curses.endwin()
return True
if __name__ == '__main__':
screen = curses.initscr()
HelloWorld().cmdloop()
I find that I'm not seeing anything when I type. curses is presumably waiting for a refresh before displaying anything on the screen. I could switch to using getch() but then I'd lose the value of cmd.
Is there a way to make these work together?
The question seems to be very old... But it attracted enough of attention so i thought to leave my answer behind.. You can check out the site here and clear your doubts..
Update : this answer links to the gist from the original questioner. Just to save someone having to follow the link ... here's the code in full :
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import curses
import curses.textpad
import cmd
def maketextbox(h,w,y,x,value="",deco=None,textColorpair=0,decoColorpair=0):
# thanks to http://stackoverflow.com/a/5326195/8482 for this
nw = curses.newwin(h,w,y,x)
txtbox = curses.textpad.Textbox(nw,insert_mode=True)
if deco=="frame":
screen.attron(decoColorpair)
curses.textpad.rectangle(screen,y-1,x-1,y+h,x+w)
screen.attroff(decoColorpair)
elif deco=="underline":
screen.hline(y+1,x,underlineChr,w,decoColorpair)
nw.addstr(0,0,value,textColorpair)
nw.attron(textColorpair)
screen.refresh()
return nw,txtbox
class Commands(cmd.Cmd):
"""Simple command processor example."""
def __init__(self):
cmd.Cmd.__init__(self)
self.prompt = "> "
self.intro = "Welcome to console!" ## defaults to None
def do_greet(self, line):
self.write("hello "+line)
def default(self,line) :
self.write("Don't understand '" + line + "'")
def do_quit(self, line):
curses.endwin()
return True
def write(self,text) :
screen.clear()
textwin.clear()
screen.addstr(3,0,text)
screen.refresh()
if __name__ == '__main__':
screen = curses.initscr()
curses.noecho()
textwin,textbox = maketextbox(1,40, 1,1,"")
flag = False
while not flag :
text = textbox.edit()
curses.beep()
flag = Commands().onecmd(text)

Using subprocess in a curses application

I'm creating an application that uses curses to build a simple user interface. It also uses the subprocess module to run external text editor so a user can type some text, then close the editor and go back to the main program.
The problem is that when the editor is console-based such as Vim or Nano, curses doesn't de-initialize properly. Which means if the color mode is used (curses.start_color()), terminal stays colored after the program is finished.
Here's a test script that has this issue (at least for me, I use Ubuntu and gnome-terminal):
import curses
import subprocess
screen = curses.initscr()
curses.noecho()
curses.cbreak()
screen.keypad(1)
try:
curses.curs_set(0)
except curses.error:
pass
curses.start_color()
screen.addstr(0, 0, 'hello, world!')
screen.refresh()
while 1:
c = screen.getch()
if c == ord('q'):
break
if c == ord('r'):
subprocess.call('vim', shell=False)
screen.clear()
screen.addstr(0, 0, 'hello, world!')
screen.refresh()
curses.nocbreak()
screen.keypad(0)
curses.echo()
curses.curs_set(1)
curses.endwin()
(Press r to enter Vim, then q to exit.)
Is there a way to fix this?
Would modifying your code to:
if c == ord('q'):
subprocess.call('reset', shell=False)
break
be enough for you? Or is there some additional behaviour in your real script that is not in the code you pasted here, that makes this workaround unsuitable to your goal?

Categories

Resources