简体   繁体   English

使用Python curses突出显示和选择文本

[英]Highlighting and Selecting text with Python curses

This is my first post to stack overflow. 这是我发布堆栈溢出的第一篇文章。 I've been lurking this site for information for years, and it's always helpful, so I thought that I would post my first question. 多年来我一直潜伏在这个网站上获取信息,它总是有用的,所以我想我会发布我的第一个问题。

I've been searching for some similar examples, but can't seem to find anything. 我一直在寻找一些类似的例子,但似乎找不到任何东西。

Ultimately, I'm trying to write a simple text ui for finding false positives and false negatives in a text extraction program. 最终,我正在尝试编写一个简单的文本ui,用于在文本提取程序中查找误报和漏报。 The false positive module is a simple yes/no selection, and displaying colored text and using getch() is easy enough. 误报模块是一个简单的是/否选择,显示彩色文本和使用getch()很容易。 The False negative portion however, is a becoming difficult. 然而,假阴性部分变得困难。

So this is what I want to do: 所以这就是我想要做的:

  1. Display a string onto the screen (forget scrolling for now.... ugh) It will only be a string with no newlines. 在屏幕上显示一个字符串(暂时忘记滚动......呃)它只是一个没有换行符的字符串。
  2. The user sees the text, and pushes 'h' to enter highlight mode. 用户看到文本,然后按“h”进入高亮模式。
  3. The user can then control the cursor to move it over a portion of the text (still displayed), and select 'v' to begin highlighting (I trying to make this as close to vi as I can) 然后用户可以控制光标将其移动到文本的一部分上(仍然显示),并选择“v”开始突出显示(我试图尽可能接近vi)
  4. The user then uses control keys (arrows, hjkl) to move the cursor from a starting point to and end point, highlighting the text on the way. 然后,用户使用控制键(箭头,hjkl)将光标从起点移动到终点,突出显示路上的文本。 This highlighted portion should be a word which is a false negative 这个突出显示的部分应该是一个假阴性的词
  5. The user presses some key ('y' probably), and the selected text is colored, or stays highlighted, and the highlighted text is save to some variable that I'll handle later. 用户按下一些键(可能是'y'),所选文本被着色,或保持高亮显示,突出显示的文本将保存到稍后我将处理的某个变量中。
  6. The user exits highlight mode and proceeds. 用户退出高亮模式并继续。

Any ideas to even START? 有什么想法甚至开始吗? I'm trying simple things like keeping text on the screen and moving the cursor around, but to no avail. 我正在尝试简单的事情,比如在屏幕上保留文字并移动光标,但无济于事。

I'm aware of the curses.textpad.TextBox() module, but it performs editing like insertion and deletion, which I don't want to do. 我知道curses.textpad.TextBox()模块,但它执行编辑,如插入和删除,我不想这样做。 Perhaps there is a way to disable it. 也许有一种方法可以禁用它。

I have other questions, but I'll keep this specific for now. 我还有其他问题,但我现在还会详细说明。

Thanks!! 谢谢!!

Neal 尼尔

Edit: To be more specific, I'm not looking for help writing the whole program, just help moving the cursor over displayed text, highlighting it, and selecting it and saVing it in a variable. 编辑:更具体地说,我不是在寻找编写整个程序的帮助,只是帮助将光标移动到显示的文本上,突出显示它,然后选择它并在变量中保存它。

I would like to update this question in case anybody else is searching the web for this and stumbles upon this question. 我想更新这个问题,以防其他人在网上搜索这个问题并偶然发现这个问题。

Okay, so the answer was actually quite simple and required reading all the functions listed on the python curses documentation. 好的,所以答案实际上非常简单,需要阅读python curses文档中列出的所有函数。

What I did was make a 3 state machine: State 1: Normal mode (displays text only), State 2: highlight mode, allow the cursor to move around the window, and State 3: highlighter mode, which gives only limited movement from left to right over texts and highlights the text as it's moving. 我做的是制作一个3状态机:状态1:正常模式(仅显示文本),状态2:高亮模式,允许光标在窗口周围移动,以及状态3:荧光笔模式,从左侧仅提供有限的移动直到文本并在文本移动时突出显示文本。

To accomplish this task, it just takes some basic curses function calls. 要完成此任务,只需要一些基本的curses函数调用。

I made separate windows, but I'll just assume a single window for explaination. 我制作了单独的窗口,但我只假设一个窗口进行解释。

Do display text in the window, stick with the: 在窗口中显示文字,坚持:

window.addstr()
window.refresh()

For moving the cursor around: 用于移动光标:

#get current cursor position
curr_y, curr_x = window.getyx()

# depending on direction, update the cursor with
next_y, next_x = get_next_direction()

# place cursor in new position
window.move(next_y, next_x)

window.refresh()

Once the cursor is over the starting point for highlighting, press 'v' enter the highlighter state, and limit the movement of the cursor, change the attribute of the selected text: 一旦光标超过突出显示的起始点,按'v'进入荧光笔状态,并限制光标的移动,更改所选文本的属性:

# get current cursor position
curr_y, curr_x = window.getyx()

# save position for later use
start_y = curr_y; start_x = curr_x

# loop until 'v' is pressed again
while highlight_state:
    # change the attribute of the current character, for 1 character only, to reverse
    window.chgat(curr_y,curr_x, 1, curses.A_REVERSE)
    curr_y, curr_x = get_next_direction()

# save end state, this is buggy obviously, but you get the point
end_y = curr_y; end_x = curr_X

Now extract that information from start to end 现在从头到尾提取该信息

# get integer representation of char at positiong

outstr = ''
#from start to end
char_as_int = windows.inch(y,x)
char = char_as_int & 0000FF
attr = char_as_int & FFFF00 #not useful here, but maybe later

outstr += char

That's it! 而已! I also tried another way to save the highlighted material which was basically transformat the x,y coordinates to the index of the string that was being display, but that let to issue in string representation (newlines, tabs, and so on), plus was just harder to do. 我还尝试了另一种方法来保存突出显示的材料,它基本上将x,y坐标转换为正在显示的字符串的索引,但是允许以字符串表示形式(换行符,制表符等)发出,加上更难做到。

If anyone has comments of a more efficient/ cleaner method, please respond! 如果有人对更有效/更清洁的方法有意见,请回复!

I don't know anything about ncurses, but using Tkinter or one of the other GUI toolkits, it could be done with a canvas. 我对ncurses一无所知,但是使用Tkinter或其他GUI工具包之一,它可以用画布完成。 You would first set the scroll region, then bind the "h" key so it sets a highlight variable to True, bind a mouse click to a function that retrieves the location to start, bind the left and right arrows to move left or right one letter, and move the cursor and reverse the colors of the next letter as well as keep track of how many letters you are from the starting point, which also tells you the end location, and bind "y" to copy the text. 您首先设置滚动区域,然后绑定“h”键,使其将高亮变量设置为True,将鼠标单击绑定到检索要开始的位置的函数,绑定左右箭头以向左或向右移动字母,并移动光标并反转下一个字母的颜色,并跟踪起始点的字母数,也告诉您结束位置,并绑定“y”复制文本。

It is not as complicated as it might seem as each part is a fairly simple function. 它并不像看起来那么复杂,因为每个部分都是一个相当简单的功能。 All of this would of course depend on the font size, and I would suggest displaying the text with a fixed font so each letter occupies the same width. 所有这些当然取决于字体大小,我建议用固定字体显示文本,这样每个字母占据相同的宽度。 Once again, I do not know ncurses, but it would be similiar with any toolkit. 再一次,我不知道ncurses,但它会与任何工具包类似。 If you can work it around so that the user can select one entire line with a mouse click, it makes the coding much easier. 如果您可以使用它,以便用户可以通过鼠标单击选择一整行,这使编码更容易。 Post back with some code if you do indeed decide to go with Tkinter or wxPython and want some additional help. 如果您确实决定使用Tkinter或wxPython并想要一些额外的帮助,请回复一些代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM