QT setInputMask() : how to interpolate string with user input in QLineEdit - qt

I want the user to enter the input in QLineEdit in the following format
Array {99, 99, 99, 99}
where
1) Array { } is already present in the lineEdit. User only enters comma separated integers.
2) The no. of integers entered may vary.
I tried using setInputMask() for task (1) (backslashes to escape characters)
setInputMask("\A\r\r\a\y\{99\, 99\, 99\}");
But this does not work. Please help.

Disclaimer: This is a partial answer.
For your task (1), you should use double back-slashes to escape them. From the documentation (and in your case), only the following need to be escaped: A, a, {, }.
setInputMask("\\Arr\\ay\\{99\\,99\\,99\\}");
Otherwise, the compiler would (should) warn you about warning: unknown escape sequence: '\S'
With task (2), an idea would be to subclass QLineEdit, and dynamically update the inputMask() at every keypress by overloading keyPressEvent(). Another idea would be to set an input mask with, say, a hundred 99 or x's then to use a regex to validate user input.

Related

How to replace a string pattern with different strings quickly?

For example, I have many HTML tabs to style, they use different classes, and will have different backgrounds. Background images files have names corresponding to class names.
The way I found to do it is yank:
.tab.home {
background: ...home.jpg...
}
then paste, then :s/home/about.
This is to be repeated for a few times. I found that & can be used to repeat last substitute, but only for the same target string. What is the quickest way to repeat a substitute with different target string?
Alternatively, probably there are more efficient ways to do such a thing?
I had a quick play with some vim macro magic and came up with the following idea... I apologise for the length. I thought it best to explain the steps..
First, place the text block you want to repeat into a register (I picked register z), so with the cursor at the beginning of the .tab line I pressed "z3Y (select reg z and yank 3 lines).
Then I entered the series of VIM commands I wanted into the buffer as )"zp:.,%s/home/. (Just press i and type the commands)
This translate to;
) go the end of the current '{}' block,
"zp paste a copy of the text in register z,
.,%s/home/ which has two tricks.
The .,% ensures the substitution applies to everything from the start of the .tab to the end of the closing }, and,
The command is incomplete (ie, does not have a at the end), so vim will prompt me to complete the command.
Note that while %s/// will perform a substitution across every line of the file, it is important to realise that % is an alias for range 1,$. Using 1,% as a range, causes the % to be used as the 'jump to matching parenthesis' operator, resulting in a range from the current line to the end of the % match. (which in this example, is the closing brace in the block)
Then, after placing the cursor on the ) at the beginning of the line, I typed "qy$ which means yank all characters to the end of the line into register q.
This is important, because simply yanking the line with Y will include a carriage return in the register, and will cause the macro to fail.
I then executed the content of register q with #q and I was prompted to complete the s/home/ on the command line.
After typing the replacement text and pressing enter, the pasted block (from register z) appeared in the buffer with the substitutions already applied.
At this point you can repeat the last #qby simple typing ##. You don't even need to move the cursor down to the end of the block because the ) at the start of the macro does that for you.
This effectively reduces the process of yanking the original text, inserting it, and executing two manual replace commands into a simple ##.
You can safely delete the macro string from your edit buffer when done.
This is incredibly vim-ish, and might waste a bit of time getting it right, but it could save you even more when you do.
Vim macro's might be the trick you are looking for.
From the manual, I found :s//new-replacement. Seemed to be too much typing.
Looking for a better answer.

how to use strings as associative array keys?

I am writing a simple GUI in AutoHotkey, one of the elements is the ability to associate a number with a button label:
Call:
{
book := {"Tel Maison": 8912, "Tel Mobile": 000000}
nr := book[%A_GuiControl%]
MsgBox %A_GuiControl% - number: %nr%
}
CapsLock::
Gui, Add, Button, gCall, Tel Maison
Gui, Add, Button, gCall, Tel Mobile
Gui, Show
When running this script I get, upon pressing a button, an error message (The following variable name contains an illegal caracter: "Tel Maison") pointing to
nr := book[%A_GuiControl%]
I believe that this is due to the space character in the label name.
Q1: isn't it possible to use hash keys with a space?
I modified the script to
Call:
{
book := {"TelMaison": 8912, "TelMobile": 000000}
nr := book[%A_GuiControl%]
MsgBox %A_GuiControl% - number: %nr%
}
CapsLock::
Gui, Add, Button, gCall, TelMaison
Gui, Add, Button, gCall, TelMobile
Gui, Show
It now runs but the variable nr is empty.
Q2: The label is passed via A_GuiControl as a string, right? If so why isn't there a match for the key in the example above?
I also tried to use book := {TelMaison: 8912, TelMobile: 000000} but the result is the same
This is a typical example of expressions vs. string literals in AHK, which can be troublesome in some cases. In order to use variable contents as a key for an object, simply put the variable in the brackets and don't enclose them in percentage signs (%):
nr := book[A_GuiControl]
This way, you can very well use spaces for the button names.
What's the problem with book[%A_GuiControl%]?
AHK expects either a hard-coded string (e.g. book["Tel Maison"]) or a variable when you access an object property by key. Since we don't pass it a hard string, it's assuming that TelMaison or Tel Maison is the variable name. Accessing Tel Maison will directly lead to a runtime error, since variable names can't have spaces. TelMaison is legal, but contains nothing. So basically, we access the object with an empty string as the key (like book[""]). This, by the way, isn't illegal and you could in fact use the empty string as a key, although I think that's not reasonable in most cases.
Why does AHK offer this weird syntax then?
There are scenarios in which you might want to use the contents of a variable in turn as a variable name. Look at this example for instance:
TelMaison := 8912
TelMobile := 0
Gui, Add, Button, gCall, TelMaison
Gui, Add, Button, gCall, TelMobile
Gui, Show
Exit
Call:
nr := %A_GuiControl%
msgbox % nr
return
With nr := %A_GuiControl%, nr is assigned the value of the variable, whose name is equal to the contents of A_GuiControl. I wouldn't recommend this pattern though, since it's very error-prone and simply bad design.

TALES expression to compare numeric input in Plone?

TALES expression is new to me. Can I get some good reference for the same? Actually I wish to define a content rule for numeric input field using ploneformgen. Something like:
python: request.form.get('amt', False) <= 5000
then apply the rule.
Here 'amt' is a numeric/whole number field on the input form.
For reference, you should look at the official TALES specification, or refer to the TALES section of the Zope Page Templates reference.
In this case, you are using a plain python expression, and thus the normal rules of python code apply.
The expression request.form.get('amt', False) would return the request parameter 'amt' from the request, and if that's missing, return the boolean False, which you then compare to an integer value.
There are 2 things wrong with that expression: first of all you assume that the 'amt' parameter is an integer value. Even a PFG integer field however, is still a string in the request object. As such you'll need to convert in to an integer first before you can compare it.
Also, you fall back to a boolean, which in integer comparisons will be regarded as the equivalent of 0, better be explicit and use that instead:
python: int(request.form.get('amt', 0)) <= 5000
Note that for a PFG condition, you can also return a string error message instead of boolean True:
python: int(request.form.get('amt', 0)) <= 5000 or 'Amount must be not be greater than 5000'
Usually form parameters are passed in as strings if they are not defined on the application level otherwise e.g.
Zope will under the hood use the fieldname amt:int in order to convert the value to an integer.
So you may want to try to put an int(....) around the first expression.

RegularExpression Validator For Textbox

In my requirement a Textbox should allow Alphabets,Numeric s, Special Characters,Special Symbols With at least one Alphabet.
I will try like this but i am not getting.
^\d*[a-zA-Z][a-zA-Z0-9#*,$._&% -!><^#]*$
You may want to have 2 regular expression validators; one for validating the allowed characters, and one for validating that at least on alphabet has been provided. You may be able to get at least one, but this way, you can have two separate validation messages to show the user explaining why the input is wrong.
Just match for special characters until you encounter a letter, then match for everything until the end of the string:
^[0-9#*,$._&% -!><^#]*[a-zA-Z0-9#*,$._&% -!><^#]*$
Use lookaheads :
/^(?=.*[a-zA-Z])[\w#*,$.&%!><^#-]*$/
Edit :
I assume the - is meant as the actual - character and not a range of space to !.
I removed the space character. You can of course add it if you want.
[ -!]
Effectively means :
[ -!] # Match a single character in the range between “ ” and “!”
And I have no idea what that range entails!

^[[A character combination

On Unix, when I press up arrow key, it shows this string, but while scanf, it does not take it as input. Please explain how to take it as input. Can we something like compare the character by charater like first ^[ is Esc key and so on?
That's the escape sequence generated by that key. '^[' is CTRL-[ (the ESC character), and the other two characters are '[' and 'A'.
If you want to process them, you'll need to read all three characters and decide that they mean the user pressed the up-arrow key.
Whether or not you can do this with your scanf depends on the format string. I would be using a lower level of character input for this.
I never use [f]scanf in real code since failure results in you not knowing where the input pointer is located. For line-based input, I find it's always better to use fgets and then sscanf the string retrieved.
But, as I said, you should be using getc and its brethren for low-level character I/O. Or find a higher level function such as readline under Linux, or other libraries that know to convert it into special keycodes such as VK_KEY_UP that you can process.

Resources