Получение нажатий мыши на окне консоли для python - PullRequest
1 голос
/ 30 декабря 2011

Есть ли какой-нибудь способ получить нажатие мыши на окнах консоли в python? Я знаю, что вы можете сделать это, потому что, если вы работаете в Windows, вы можете открыть cmd и набрать "edit" Как бы вы сделали это, например, в Python? Спасибо.

Ответы [ 3 ]

3 голосов
/ 01 августа 2015

Мне лично не нравится PyWin32 из последнего ответа за то, что он работает только при первом импорте, после чего не может импортировать свой основной модуль pyd.
и тут дело в том, что это не кроссплатформенность.

curses - лучшая альтернатива, хотя она не совсем подходит для python27, но мне удалось заставить ее работать в Wine:

import _curses # _curses.pyd supplied locally for python27 win32
import curses 

screen = curses.initscr() 
#curses.noecho() 
curses.curs_set(0) 
screen.keypad(1) 
curses.mousemask(curses.ALL_MOUSE_EVENTS)

screen.addstr("This is a Sample Curses Script\n\n") 

key=0
while key!=27: # Esc to close
    key = screen.getch() 
    #screen.erase()
    if key == curses.KEY_MOUSE:
        _, mx, my, _, _ = curses.getmouse()
        y, x = screen.getyx()
        screen.addstr('mx, my = %i,%i                \r'%(mx,my))
    screen.refresh()

curses.endwin()

в этом примере вам нужно нажать, перетащить и отпустить, чтобы событие зарегистрировалось, но я думаю, что есть способ обойти это.

Я просто играю с этим сам (не хочу усложнять PyQt или PyGLFW)

EDIT:
удалось заставить его работать как положено и обновил код. Вам не нужно больше перетаскивать, чтобы событие зарегистрировалось.

1 голос
/ 17 сентября 2015

Оба предыдущих ответа верны: вы можете использовать pywin32 в Windows или curses в Linux для управления вводом с помощью мыши.Однако ни одна из них не работает на другой платформе.

Если вы хотите что-то, что обрабатывает оба или просто более простой API, вы можете использовать пакет, который я недавно написал - asciimatics.Класс Screen обрабатывает ввод с помощью мыши для консоли кросс-платформенным способом, объединяя оба вышеуказанных решения.

0 голосов
/ 17 апреля 2012

Да, но это большой объем работы.

http://sourceforge.net/projects/pywin32/files/

Он работает так же, как общение с Win32API из кода C.

Документация Microsoftочень хорошо, если вы используете Google для имен функций в MSDN.

pywin32 включает файл с именем win32console_demo.py

Добавьте следующую строку, чтобы включить ввод с помощью мыши.Сразу после создания conin.

conin.SetConsoleMode(ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT)

win32console_demo.py отредактирован для включения ввода мышью.

import win32con
import win32file
from win32console import *
import traceback, time


virtual_keys={}
for k,v in win32con.__dict__.items():
    if k.startswith('VK_'):
        virtual_keys[v]=k 

free_console=True
try:
    AllocConsole()
except error, exc:
    if exc.winerror!=5:
        raise
    ## only free console if one was created successfully
    free_console=False

stdout=GetStdHandle(STD_OUTPUT_HANDLE)

conin=PyConsoleScreenBufferType( win32file.CreateFile( "CONIN$", win32con.GENERIC_READ|win32con.GENERIC_WRITE, win32con.FILE_SHARE_READ, None, win32con.OPEN_EXISTING, 0, 0))

conin.SetConsoleMode(ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT)

newbuffer=CreateConsoleScreenBuffer()
newbuffer.SetConsoleActiveScreenBuffer()
newbuffer.SetConsoleTextAttribute(FOREGROUND_RED|FOREGROUND_INTENSITY
        |BACKGROUND_GREEN|BACKGROUND_INTENSITY)
newbuffer.WriteConsole('This is a new screen buffer\n')

newbuffer.SetConsoleTextAttribute(FOREGROUND_RED|FOREGROUND_INTENSITY
        |BACKGROUND_GREEN|BACKGROUND_INTENSITY)
newbuffer.WriteConsole('Press some keys, click some characters with the mouse\n')

newbuffer.SetConsoleTextAttribute(FOREGROUND_BLUE|FOREGROUND_INTENSITY
        |BACKGROUND_RED|BACKGROUND_INTENSITY)
newbuffer.WriteConsole('Hit "Esc" key to quit\n')


breakout=False
while not breakout:
    input_records=conin.ReadConsoleInput(10)
    for input_record in input_records:
        if input_record.EventType==KEY_EVENT:
            if input_record.KeyDown:
                if input_record.Char=='\0':
                    newbuffer.WriteConsole(virtual_keys.get(input_record.VirtualKeyCode, 'VirtualKeyCode: %s' %input_record.VirtualKeyCode))
                else:
                    newbuffer.WriteConsole(input_record.Char)
                if input_record.VirtualKeyCode==win32con.VK_ESCAPE:
                    breakout=True
                    break
        elif input_record.EventType==MOUSE_EVENT:
            if input_record.EventFlags==0:  ## 0 indicates a button event
                if input_record.ButtonState!=0:   ## exclude button releases
                    pos=input_record.MousePosition
                    # switch the foreground and background colors of the character that was clicked
                    attr=newbuffer.ReadConsoleOutputAttribute(Length=1, ReadCoord=pos)[0]
                    new_attr=attr
                    if attr&FOREGROUND_BLUE:
                        new_attr=(new_attr&~FOREGROUND_BLUE)|BACKGROUND_BLUE
                    if attr&FOREGROUND_RED:
                        new_attr=(new_attr&~FOREGROUND_RED)|BACKGROUND_RED
                    if attr&FOREGROUND_GREEN:
                        new_attr=(new_attr&~FOREGROUND_GREEN)|BACKGROUND_GREEN

                    if attr&BACKGROUND_BLUE:
                        new_attr=(new_attr&~BACKGROUND_BLUE)|FOREGROUND_BLUE
                    if attr&BACKGROUND_RED:
                        new_attr=(new_attr&~BACKGROUND_RED)|FOREGROUND_RED
                    if attr&BACKGROUND_GREEN:
                        new_attr=(new_attr&~BACKGROUND_GREEN)|FOREGROUND_GREEN
                    newbuffer.WriteConsoleOutputAttribute((new_attr,),pos)
        else:
            newbuffer.WriteConsole(str(input_record))
    time.sleep(0.1)

newbuffer.Close()

if free_console:
     FreeConsole()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...