I've read several tutorials for PyQt and they use an ampersand character (&) in Strings which are used to label buttons. For example:
self.submitButton = QPushButton("&Submit")
I searched for some explanation, but one problem is, that common search engines think they're so smart and ignore the & character, which is annoying. When I add quotes around it, it only makes me find less results and none, which explains anything about strange '&' characters.
Is it something very basic and that's why no one is explaining it?
Or is it PyQt specific?
And why would I add an unnecessary character like that?
Doesn't it only clutter the String unnecessarily?
What kind of effect does it have on the handling of that String?
I also tried in the python console:
a = "&abc"
b = "abc"
a == b
which returns false.
Then I tried giving it as an argument to the print function:
print(a)
print(b)
which simple prints:
&abc
abc
So I still don't know what to make of this.
From msdn.microsoft.com: (not related to python itself, but the concept is the same)
Gets or sets a value indicating whether the control interprets an
ampersand character (&) in the control's Text property to be an access
key prefix character.
If the UseMnemonic property is set to true and a mnemonic character (a
character preceded by the ampersand) is defined in the Text property
of the Label, pressing ALT+ the mnemonic character sets the focus to
the control that follows the Label in the tab order. You can use this
property to provide proper keyboard navigation to the controls on your
form.
And from pyqt.sourceforge.net:
A QLabel is often used as a label for an interactive widget. For this
use QLabel provides a useful mechanism for adding an mnemonic (see
QKeySequence) that will set the keyboard focus to the other widget.
E.g.:
QLineEdit* phoneEdit = new QLineEdit(this);
QLabel* phoneLabel = new QLabel("&Phone:", this);
phoneLabel->setBuddy(phoneEdit);
Related
Alright, so in VSCode, when you use an opening bracket, it automatically uses a closing bracket. Instead, I want this to be angle brackets. How would I do this? For example:
Presses: <
Output: <>
Thanks in advance!
Edit: I'm going to clarify this. I'm doing this in a Tkinter text widget. So pressing < will insert a >. Soory for the lack of clarity.
A really simple solution is to bind a function to <KeyRelease>, since that will fire after the default bindings have actually inserted the character into the widget. Or, you could bind to <KeyPress> and manage inserting both the start original character and its closing character.
Let's start by defining a dictionary which defines which characters have matching characters. In this case we'll just use {} and <> for simplicity:
matched_pairs = {"{": "}", "<": ">"}
Next, lets define a function which examines the event to see if it is for a character which in in our dictionary. If we find a matching character we do two things: we insert the matching character, then move the insertion point back one so that the insertion character is between the pairs of characters.
def maybe_insert_matching_pair(event):
matching = matched_pairs.get(event.char, None)
if matching:
event.widget.insert("insert", matching)
event.widget.mark_set("insert", "insert-1c")
Finally, let's bind this function to every keypress, though you could also bind it to only the keys that you know have matching pairs.
the_text_widget.bind('<KeyRelease>', maybe_insert_matching_pair)
As a coding challenge, I've been building a rich-text editor. So far, I've made working save/save as/load systems and working Headers. But, when you save as .txt all the heading data is lost. So I've been thinking about doing a system that relies on '#' to mark headers (basically syntax highlighting)(#-H1,##-H2,###-H3...). I've looked around, and haven't found anything of the sort. So far, I use this as my system of headings:
editor.tag_configure('heading7', font=heading7_font)
removeTags()
editor.tag_add('heading7', SEL_FIRST, SEL_LAST)
*heading7_font=("Consolas Bold", 16), removeTags(): lists through tags and removes all.
Basically, you just select on an OptionMenu if you wish to change the fontsize (or use a certain bind). This question is problably too vague, but, I would very much like so direction or an answer.
Here's the code of my entire project (YES, I know I'm not using classes, and it's a jittery mess, but, I'm going to work on that later): https://pastebin.com/wthVT6q4 (Here's the stylesheet variables: https://pastebin.com/WrX4EDKM)
You can use the text widget search method to search for a string or a pattern. Then it's just a matter of applying the tag to the results.
This is how it is documented in the Text class:
search(self, pattern, index, stopindex=None, forwards=None, backwards=None, exact=None, regexp=None, nocase=None, count=None, elide=None)
Search PATTERN beginning from INDEX until STOPINDEX.
Return the index of the first character of a match or an
empty string.
As you can see, you can use the search method to search on a regular expression. Since you won't always know the length of the matched text, you can specify an IntVar to be given the count of the matching characters.
For example, to search for a line that begins with ## you can do something like this:
count_var = tk.IntVar()
index = editor.search(r'## .*', "1.0", "end", count=count_var, regexp=True)
With that, you can use index as the start of the range, and "{} +{} chars".format(index, count_var.get()) for the end of the range. Or, use "{} lineend".format(index)" to add the highlight to the entire line.
If you only want to highlight the characters after ##, you can adjust index in a similar way: "{}+{}chars".format(index, 3)
Note: the regular expression syntax must follow the rules of Tcl regular expressions. Conceptually the same, they differ from python's rules in some of the special character classes.
I am reading some code about Readline Library I try to type readline.get_completer_delims() it gives me delimiters like ~!##$%^&*()-=+[{]}\|;:'",<>/?
My question is what the meaning of those delimiters for tab complete? can someone explain ?
readline.get_completer_delims()
Per the docs:
Set or get the word delimiters for completion. These determine the start of the word to be considered for completion (the completion scope). These functions access the rl_completer_word_break_characters variable in the underlying library.
These are characters after which the tab completer should consider the start of a "word", and ignore characters on the line prior to that one. For example, if you wanted to implement a tab completer for attributes and methods on Python objects you might add . to this list, so when hitting tab after a . it would indicate that you want completion for whatever comes after the dot.
this might be a bit of an edge case, but I'm hoping it's still possible.. I want to set the '&' key as a shortcut for one of my menus. Currently, the code looks like given below, which correctly displays the ampersand, but does not set it as shortcut key. Furthermore, replacing it with the string "'&&&' as Separator" will highlight the single quote as the shortcut key for this menu item. Is this doable at all?
...
settingsAmpersand = settingsmenu.Append(wx.ID_ANY, "'&&' as Separator", " Set the separator to ampersand", wx.ITEM_RADIO);
...
from the docs
... An accelerator key can be specified using the ampersand &
character. In order to embed an ampersand character in the menu item
text, the ampersand must be doubled.
Optionally you can specify also an accelerator string appending a tab
character \t followed by a valid key combination (e.g. CTRL+V ). Its
general syntax is any combination of "CTRL" , "RAWCTRL" , "ALT" and
"SHIFT" strings (case doesn’t matter) separated by either '-' or '+'
characters and followed by the accelerator itself. Notice that CTRL
corresponds to the “Ctrl” key on most platforms but not under Mac OS
where it is mapped to “Cmd” key on Mac keyboard. Usually this is
exactly what you want in portable code but if you really need to use
the (rarely used for this purpose) “Ctrl” key even under Mac, you may
use RAWCTRL to prevent this mapping. Under the other platforms RAWCTRL
is the same as plain CTRL .
so maybe
settingsmenu.Append(wx.ID_ANY, "'&&' as Separator\tCTRL+&", " Set the separator to ampersand"...
might work... maybe... I cant really test it atm (you should have provided a complete working example)
In Python 2, I’m using str.format() to align a bunch of columns of text I’m printing to a terminal. Basically, it’s a table, but I’m not printing any borders or anything—it’s simply rows of text, aligned into columns.
With no color-fiddling, everything prints as expected.
If I wrap an entire row (i.e., one print statement) with ANSI color codes, everything prints as expected.
However: If I try to make each column a different color within a row, the alignment is thrown off. Technically, the alignment is preserved; it’s the fill characters (spaces) that aren’t printing as desired; in fact, the fill characters seem to be completely removed.
I’ve verified the same issue with both colorama and xtermcolor. The results were the same. Therefore, I’m certain the issue has to do with str.format() not playing well with ANSI escape sequences in the middle of a string.
But I don’t know what to do about it! :( I would really like to know if there’s any kind of workaround for this problem.
Color and alignment are powerful tools for improving readability, and readability is an important part of software usability. It would mean a lot to me if this could be accomplished without manually aligning each column of text.
Little help? ☺
This is a very late answer, left as bread crumbs for anyone who finds this page while struggling to format text with built-in ANSI color codes.
byoungb's comment about making padding decisions on the length of pre-colorized text is exactly right. But if you already have colored text, here's a work-around:
See my ansiwrap module on PyPI. Its primary purpose is providing textwrap for ANSI-colored text, but it also exports ansilen() which tells you "how long would this string be if it didn't contain ANSI control codes?" It's quite useful in making formatting, column-width, and wrapping decisions on pre-colored text. Add width - ansilen(s) spaces to the end or beginning of s to left (or respectively, right) justify s in a column of your desired width. E.g.:
def ansi_ljust(s, width):
needed = width - ansilen(s)
if needed > 0:
return s + ' ' * needed
else:
return s
Also, if you need to split, truncate, or combine colored text at some point, you will find that ANSI's stateful nature makes that a chore. You may find ansi_terminate_lines() helpful; it "patch up" a list of sub-strings so that each has independent, self-standing ANSI codes with equivalent effect as the original string.
The latest versions of ansicolors also contain an equivalent implementation of ansilen().
Python doesn't distinguish between 'normal' characters and ANSI colour codes, which are also characters that the terminal interprets.
In other words, printing '\x1b[92m' to a terminal may change the terminal text colour, Python doesn't see that as anything but a set of 5 characters. If you use print repr(line) instead, python will print the string literal form instead, including using escape codes for non-ASCII printable characters (so the ESC ASCII code, 27, is displayed as \x1b) to see how many have been added.
You'll need to adjust your column alignments manually to allow for those extra characters.
Without your actual code, that's hard for us to help you with though.
Also late to the party. Had this same issue dealing with color and alignment. Here is a function I wrote which adds padding to a string that has characters that are 'invisible' by default, such as escape sequences.
def ljustcolor(text: str, padding: int, char=" ") -> str:
import re
pattern = r'(?:\x1B[#-_]|[\x80-\x9F])[0-?]*[ -/]*[#-~]'
matches = re.findall(pattern, text)
offset = sum(len(match) for match in matches)
return text.ljust(padding + offset,char[0])
The pattern matches all ansi escape sequences, including color codes. We then get the total length of all matches which will serve as our offset when we add it to the padding value in ljust.