How to use QlineEdit to enter integer values - c++

I am trying to use QlineEdit.
How would I enter a value into the edit bar when I run the program and get that valued stored as a variable to be used later. So far I have only found out how to enter text using
void parameter_settings::on_lineEdit_textEdited(const QString &arg1)
{
ui->lineEdit->setText("");
}
I have a GUI that requires the user to enter a value within a specific range. That value would be stored as a variable for later use. I have read about validators but can't get it to work as intended.

I am not entirely sure what your question is, but you can get the input from a QLineEdit with the command text():
QString input = ui->lineEdit->text();
and an integer input by using:
int integer_value = ui->lineEdit->text().toInt();
As you mentioned validators: You can use validators to allow the user to insert only integers into the QLineEdit in the first place. There are different ones but I generally like to use 'RegEx' validators. In this case:
QRegExpValidator* rxv = new QRegExpValidator(QRegExp("\\d*"), this); // only pos
QRegExpValidator* rxv = new QRegExpValidator(QRegExp("[+-]?\\d*"), this); // pos and neg
ui->lineEdit->setValidator(rxv);
Note: As mentioned in the comments by Pratham, if you only require integers to be entered you should probably use a QSpinBox which does all this out-of-the-box and comes with extra handles to easily increase and decrease of the value.

Use this method:
QString str = QString::number(4.4);
ui->lineEdit->setText(str);

Related

using one Qcombobox to set value to several labels, C++

im trying to set the value from a combobox to multiple Qlabels, the idea is to populate the QcomboBox with all the values, then according to the number, (ejem 15.6) the corresponding label should change the problem is, theres too many of them to simply use a switch of something similar, but all the names of the labels are similar, HumSec_val156 corresponds to 15.6 the main idea was to use
Silo* silo = new Silo;
QString number = widget.QComboBox->currentText();
QString nameOfLabel = "HumSec_val";
nameOfLabel.append(QString::number(number));
silo->findchild<QLabel*>(nameOfLabel)->setText(valuefromCombobox);
but everytime it simply return an empty string, i did try using somthing simplier like
widget.nameOfLabel->setText(valuefromComboBox);
but nameOfLabel its just a qstring so i can mix it with the code generated from designer. Any idea what can i do? do i need to create something like a scoped enum or similar?
below i add a picture of what im doing
If I would do something like this, I would probably create a QHash<QString, QLabel*> and use that as a cache to find the matching QLabel for each name.
Declaration:
QHash<QString, QLabel*> m_hash
Storing value:
m_hash[labelName] = labelPtr;
Reading value:
QLabel* labelPtr = m_hash.value(labelName, nullptr);
if (labelPtr)
{
// Access label
}
When you remove a label remember to remove it from the hash as well:
const QString key = m_hash.key(labelPtr);
m_hash.remove(key);

Add empty option to List Validator

I'm trying to add the option to my users that, on a List Validator, to allow select any of the options or a blank option. Spreadjs has the IgnoreBlanks setting, which I use, so when the user uses the delete key or the backspace and deletes the cell it validates correctly.
However, I would love to use the same functionality as in Excel, which allows blank options in the list validator, in part of the list.
I've tried to target the <select> element that holds the list and programmatically add the empty element, however, it crashes after the user selects the empty option.
I've also tried to add different escaped characters to the list. If I select a character that represents an empty string or a tab, it won't add a new option to the list. If I use any strange character, or even the null character \0 you get a new option to select, but the content is that typical rectangle you see when your font doesn't have the character you're trying to display.
I've also tested using a regular ListValidator like in the example pages, not our custom functionality and doesn't work either.
https://www.grapecity.com/demos/spread/JS/TutorialSample/#/demos/basicDataValidator
I have also tried creating a FormulaListValidator, and if my range has empty cells I could then get an empty option on my list, however, because the range may have duplicates, I get duplicated options.
After researching a little bit I found a workaround in a different language which I adapted to Typescript (Angular 6)
export const getListValidatorFromArray = (spread: GC.Spread.Sheets.Workbook, data: any[]) => {
// saving validation list values in a hidden sheet
spread.addSheet(spread.getSheetCount());
const sheet = spread.getSheet(spread.getSheetCount() - 1);
sheet.visible(false);
for (let i = 0; i < data.length; i++) {
sheet.setValue(i, 0, data[i]);
}
// create validator based on the values
const dv = GC.Spread.Sheets.DataValidation.createFormulaListValidator(
'=' + sheet.name() + '!$A$1:' + sheet.name() + '!$A$' + data.length
);
return dv;
};
Note: This creates an extra sheet for each validator you create. Makes sure you reuse them as much as possible (i.e. assigning it to a variable when it's created, and reusing the variable for other columns/rows that use the same one).

1-indexed Model in QCombobox

I have a 1-indexed (readonly-)model and want to use it for a combobox.
I parse the data (comes from a file-parser) and have for example:
1: Variable Number 1 and that will be my first item, next
2: Variable Number 2 and so on.
When I click on an item the currentIndex()-method from QCombobox will give me a 0-indexed int, so my problem is:
I don't want to write everytime I parse a file +1 respectively -1 when writing back to the file (although the model is readonly, I can alter the data in the file). (I have nearly 30 UIs where I need the model, and for every UI I have to parse other data)
I currently use something like:
virtual int currentIndex() const { return QComboBox::currentIndex() + 1; }
virtual void setCurrentIndex(int index) { QComboBox::setCurrentIndex(index-1); }
I know that this is not ideal, because (set-)currentIndex is not virtual. But to avoid +/-1 I used this for now.
Does anybode have a good suggestion for this problem?
If you have a custom model you could add a role that returns the "real" index value.
If you just use strings to fill the combobox, you could use the setItemData() and itemData() methods to associated your reference value.
E.g.
comboBox->addItem("Number 1", 1);
and
int refValue = comboBox->itemData(comboIndex).toInt();
The associated data can be anything that can be stored in a QVariant.

Why is QLineEdit::setCursorPosition(int) selecting(highlighting) text?

I have an editable QComboBox that allows a user to type in a name for a new object and add it to the list. They can also edit names for existing items in the list. The problem is...say I have an item in the list called "AF" and I want to rename it to "ABCDEF". My first problem was if I placed the cursor in between 'A' and 'F' and started typing the cursor would jump to the end after typing 1 letter. So I would get "ABFCDE" unless I manually moved the cursor after each letter typed.
I fixed this by using
// slot connected to textEditChanged(QString) signal from QComboBox
void textChanged(const QString &text)
{
int pos = QComboBox->lineEdit()->custorPosition();
stuff...
QComboBox->setItemText(idx, text);
QComboBox->lineEdit()->setCursorPosition(pos);
}
and that works but unfortunately this caused a new problem.
setCursorPosition will subsequently select (highlight) all text beyond the new cursor location. So in the "AF" to "ABCDEF" example... I place the cursor between 'A' and 'F', type B and the cursor stays after "AB" and before 'F' but 'F' is highlighted. The next key press will replace the 'F' entirely. It will highlight more than 1 character, it highlights every character to the right of the cursor after it is moved.
I tried this to no avail.
QComboBox->lineEdit()->deselect();
I also tried this just as a test and it incorrectly exhibited the same behavior.
QComboBox->lineEdit()->moveCursorBackward(false,2);
The false parameter is supposed to not select the text the cursor moves past but it does anyway.
Anyone have any ideas on what's causing this?
I also encountered this problem. Here's what solved it for me for anyone interested:
First connect the signal but make sure it is queued!
connect(_comboBox, SIGNAL(editTextChanged(const QString&)), this, SLOT(slotTextChanged(const QString&)), Qt::QueuedConnection);
and for the slot:
void ViewListWidget::slotViewNameChanged(const QString& /*name*/) {
int index = _viewComboBox->currentIndex();
int cursorPosition = _viewComboBox->lineEdit()->cursorPosition();
// Since we are using a queued connection, get the current QLineEdit text
// instead of relying on the signal argument, which might be out of sync
QString name = _viewComboBox->lineEdit()->text();
_viewComboBox->blockSignals(true);
_viewComboBox->setItemText(index, name);
_viewComboBox->blockSignals(false);
_viewComboBox->lineEdit()->setCursorPosition(cursorPosition);
}
You should also probably disable auto-complete:
_comboBox->setCompleter(0);

QDoubleValidator is not working?

I'm trying to apply validator in a line edit box in Qt 4.2 and it is not working:
QDoubleValidator *haha= new QDoubleValidator(this);
haha->setBottom(0.00);
haha->setDecimals(2);
haha->setTop(100.00);
get_line_edit()->setValidator(haha);
or
QDoubleValidator *haha= new QDoubleValidator(0.00,100.00,2,this);
Neither way, I can still enter what ever value I want.
But if I switch to QIntValidator, it works!
So I went onto Google and did a bit search, and many people used to having the same issue. Is it a bug? or there should be some other set up I should do?
Just tripped over this one. Try setting the QDoubleValidator notation to:
doubleValidator->setNotation(QDoubleValidator::StandardNotation);
The validator documentation says that it returns "Intermediate" from "validate" when the input is an arbitrary double but out of range.
You need to distinguish intermediate input and the final input the user wants to submit by use of a line edit control (e.g. by emitting the "returnPressed" signal). If the user typed "10000" that is still a valid intermediate input for a number between 0 and 100 because the user can prefix this input with "0.".
You have to set notation to your validator
QLineEdit *firstX;
QDoubleValidator* validFirstX = new QDoubleValidator(-1000, 1000, 3, ui.firstX);
validFirstX->setNotation(QDoubleValidator::StandardNotation);
then it works but not fully correct. Interesting part is that it controls the digit numbers not number itself. For example, In this example, you can enter to QLineEdit 1000 either 9999.
&& ( input.toDouble() > top() || input.toDouble() < bottom())
This example works fine in 4.8. It doesn't look like its changed since 4.2 so I suspect the problem lies in how you are creating your QLineEdit. This is the relevent code from that example.
QLineEdit* validatorLineEdit;
validatorLineEdit = new QLineEdit;
validatorLineEdit->setValidator( new QDoubleValidator(-999.0, 999.0, 2, validatorLineEdit));
How have you created your line edit?
To clarify, use QDoubleValidator::setNotation(QDoubleValidator::StandardNotation)
Example:
QDoubleValidator* doubleValidator = new QDoubleValidator(-999.0, 999.0, 2, validatorLineEdit);
doubleValidator->setNotation(QDoubleValidator::StandardNotation);
validatorLineEdit->setValidator(doubleValidator);
If you set a validator to a QLineEdit then you can use the function hasAcceptableInput() to check whether inputed value is valid or invalid. For example:
if (!ui->lineEdit_planned_count_vrt->hasAcceptableInput())
{
slot_show_notification_message("EDIT_PLAN_COUNT_VRT", notification_types::ERROR, INVALID_INPUTED_VALUE);
return;
}
bool isOk = false;
double value = ui->lineEdit_planned_count_vrt->text().toDouble(&isOk);
//do something with the value here....