I want to create automcomplete feature in a tkinter text widget. When the autocomplete finds a possible word, it deletes the user part-of-word, then insert the complete word:
#if some matched words are found
if self._hits != []:
#delete the part written by the user
self.text.delete("%s+1c" % Space1Index,INSERT)
#Inser the complete word
self.text.insert("%s+1c" % Space1Index,self._hits[self._hit_index])
Then I will tag the text added by the autocomplete to have a different look than the user input. For ex, if the user wrote te, autocomplete will write the complete word test. te will be with normal font, and st will be wrote in another color and waits for the user to confirm the selected word by the computer.
My question is, after inserting the word test and properly highlighting it, how can I move the INSERT position again after te?
I hope I could clarify my question enough, please let me know if more explanation is needed.
To move the insertion cursor, set the "insert" mark to wherever you want:
self.text.mark_set("insert", "%s+1c" % ...)
-or-
self.text.mark_set(INSERT, "%s+1c" % ...)
You can save the position of the insert mark before your autocompletion changes and reset the mark to the saved position after:
old_pos = self.text.index("insert")
# make autocompletion changes
self.text.mark_set("insert", old_pos)
Related
I want to make text bold work as intended, meaning for example when you want to make a selected word bold, but you mistakenly didn't select the whole word, and you left out the last letter, and then you want to correct that mistake and select the whole word, instead of bolding the word, it will change its weight to normal. Specifically I'm talking about this way of doing this:
`
def bold_it():
bold_font = font.Font(my_text, my_text.cget("font"))
bold_font.configure(weight="bold")
my_text.tag_configure("bold", font=bold_font)
current_tags = my_text.tag_names("sel.first")
if "bold" in current_tags:
my_text.tag_remove("bold", "sel.first", "sel.last")
else:
my_text.tag_add("bold", "sel.first", "sel.last")
`
I am fully aware of what the problem is, and it is in the current_tags variable, since the variable will return "bold" because tag names only looks at tags which are at the first selected position. In turn, this will make the if statements remove the bold tag instead of applying it.
So my question is, how do you fix this, or optimize this?
Codemy.com did a video on this, and this question is based on this video, https://www.youtube.com/watch?v=X6zqePBPDVU.
I tried utilizing the tag_ranges() method so I could get two indexes instead of just where the selecting begins, but it did not work because tag_names() accepts only one argument.
I have a validator which Ive attached to a wx.TextCtrl inside a wx.Dialog:
myinput = wx.TextCtrl(self, validator=MyValidator())
All that validator does is it binds a wx.EVT_CHAR event and checks whether the input is a number and whether the number of characters entered is less than 5.
The problem is when I select the text with my mouse i.e. turn it to blue I cant replace the text if the number of characters is already at its maximum.
How can I detect whether the user has selected the text of that specific text box and has pressed a key?
Take a look at how the IntValidator inside the file wx\lib\intctrl.py is created.
Now use the intctrl instead of creating your own and limit the characters entered to 4 by using the method SetMaxLength(4)
How can I get the text under the cursor? So if I hover over it and the word was "hi" I could read it? I think I need to do something with QTextCursor.WordUnderCursor but I am not really sure what. Any help?
This is what I am trying to work with right now:
textCursor = text.cursorForPosition(event.pos());
textCursor.select(QTextCursor.WordUnderCursor);
text.setTextCursor(textCursor);
word = textCursor.selectedText();
I have it selecting the text right now just so I can see it.
Edit 2:
What I am really trying to do is display a tooltip over certain words in the text.
Unfortunately, I can't test this at the moment, so this is a best guess at what you need. This is based on some code I wrote that had a textfield that showed errors in a tooltip as you typed, but should work.
You've already got code to select the word under the hover over, you just need the tooltip in the right spot.
textCursor = text.cursorForPosition(event.pos())
textCursor.select(QTextCursor.WordUnderCursor)
text.setTextCursor(textCursor)
word = textCursor.selectedText()
if meetsSomeCondition(word):
toolTipText = toolTipFromWord(word)
# Put the hover over in an easy to read spot
pos = text.cursorRect(text.textCursor()).bottomRight()
# The pos could also be set to event.pos() if you want it directly under the mouse
pos = text.mapToGlobal(pos)
QtGui.QToolTip.showText(pos,toolTipText)
I've left meetsSomeCondition() and toolTipFromWord() up to you to fill in as you don't describe those, but they are pretty descriptive in what needs to go there.
Regarding your comment on doing it without selecting the word, the easiest way to do this is to cache the cursor before you select a new one and then set it back. You can do this by calling QTextEdit.textCursor() and then setting it like you did previously.
Like so:
oldCur = text.textCursor()
textCursor.select(QTextCursor.WordUnderCursor) # line from above
text.setTextCursor(textCursor) # line from above
word = textCursor.selectedText() # line from above
text.setTextCursor(oldCur)
# if condition as above
I have looked around and I would think this to be really simple, for some reason I ahve only found parts of what I need.
I have made a text editor and I have a box that what is typed it will find the problem is that it will only find the first word the in the text view adn I can't get it to search the next line.
like a find function in a textdocument.
def search(found):
search_str = findentry.get_text()
start_iter = textbuffer.get_start_iter()
found = start_iter.forward_search(search_str,0, None)
if found:
match_start,match_end = found
textbuffer.select_range(match_start,match_end)
I thought I would be able to do a button that is a search next and make it forward search again adding something and a variable +1.
how can I make it search forward and backwards.
You are using get_start_iter(), which returns the first position in text buffer. Probably, you want to start from match_end, which is the position where word ends in the first search, that is, you should start from there.
Assuming you are returning found and calling again search with that parameter, then can replace the line:
start_iter = textbuffer.get_start_iter()
by
start_iter = found[1] if found else textbuffer.get_start_iter()
The first time, or whenever you want to reset the search, you can pass found=None.
I have a textEdit field and I want to process some selected text within this field (but not the format of it).
So far, I connect the button with:
QtCore.QObject.connect(self.ui.mytext_button,QtCore.SIGNAL("clicked()"), self.mytext)
The method:
def mytext(s):
return s.upper()
But how do I tell Python that s is the selected text? I know that is something with selectionStart(), selectionEnd(). And how to change it to what mytext returns? I think is something with insertText(), but here I am also lost at the details.
Answering my own question. Posting here for fellow Python noobs:
Get the selected text:
cursor = self.ui.editor_window.textCursor()
textSelected = cursor.selectedText()
insert back the text into your editor.
self.ui.editor_window.append(s)
There are also alternatives to append(), for inserting the text into the original text.
So, to put a selected text into uppercase:
def mytext(self):
cursor = self.ui.editor_window.textCursor()
textSelected = cursor.selectedText()
s = textSelected.upper()
self.ui.editor_window.append(s)