QLineEdit thousand separator - c++

With a QLineEdit is it possible to display the thousand separator of a number while user enter it
Which is the best way to do that ?

You can connect a slot to the void QLineEdit::textEdited ( const QString & text ) signal of your QLineEdit and add some space/separator in the edited string via the setText() method. It should work since textEdit won't be emit-ed again.
The Qt doc says :
Unlike textChanged(), this signal (textEdited) is
not emitted when the text is changed
programmatically, for example, by
calling setText().
You can take advantage of this situation to check if the string entered by the user is actually a number and correct it if needed.

Related

How to have QLabel update as various numbered pushbuttons are clicked

I have a dialpad with numbers 1-9 and 0, and a QLabel above it to show the numbers when clicked(same as a keypad on any phone). All are push buttons. What is the easiest way to get the QLabel to show the numbers as the push buttons are clicked?
For example, if 2 then 0 then 7 is clicked, the label would update in real time with 207. The format of the Qlabel should follow standard phone numbers, 000-000-0000. I understand how to setText for one number at a time, but they keep overriding each other.
Any help is appreciated.
Thank you in advance
What you are looking for is a QSignalMapper. It maps multiple inputs through a single interface and does the sender dispatching for you.
QSignalMapper *mapper(new QSignalMapper(parent));
for (int i=0; i<10; ++i){
QPushButton *button = some_new_button_function();
connect(button, &QPushButton::clicked, mapper, &QSignalMapper::map);
mapper->setMapping(button, i);
}
connect(mapper, QOverload<int>::of(&QSignalMapper::mapped),
[this](int i){/*here your append code*/});
The easiest is to connect the clicked signal of the buttons to a slot (possibly a lambda) that changes the text of the QLabel (using setText()). If you want to append to the current text, then just do setText(label.text() + "new text");.
You have to connect the signals clicked() emitted by each QPushButton to a slot that update the QLabel text.
A brief example
In the parent constructor:
connect(qpb1, &QPushButton::clicked, this, &MyClass::handleQLabel);
And the possible slot implementation:
void MyClass::handleQLabel()
{
QPushButton * qpb = qobject_cast<QPushButton*>(sender()); // Find the sender of the signal
if(qpb != nullptr)
this->myLabel->setText(qpb->text()); // Write anything you want in the QLabel
else
{
// Do what you want.
}
}
This will do the job.
Of course if you don't want use sender() (for multi-threading concerns for example) you can either create one slot by QPushButton and do the same number of connect (heavy and quite a dirty workaround), or create a subclass of QPushButton to add a custom signal to emit with an identifier of the QPushButton and get it with a slot for example.
I hope it can help :)
QLineEdit might better suit your needs in this case if you also want your data representation to follow phone number standard such as "000-000-0000". You can make it read-only, disable interaction flags if you like (but from UI/UX perspective it is better not to, since mostly there is no reason to disallow copying), and also you can set input mask you like. Given your current situation, you can base your needs on the following example:
// Set your format.
ui->lineEdit->setInputMask("000-000-0000");
// Make sure that your text would be in the format you like initially.
ui->lineEdit->setText("999-999-9999");
// Text will be not editable.
ui->lineEdit->setReadOnly(true);
// And here, you can use QSignalMapper as other members have suggested. Or you can just connect multiple buttons somehow. The choice is yours to make.
connect(ui->pushButton, &QPushButton::clicked, ui->lineEdit, [this]
{
// Just keep in mind taht when returning text, some of the mask elements might be here, too.
ui->lineEdit->setText(ui->lineEdit->text().replace("-", "") + "1");
});

Add copied text to a lineEdit when a button is pushed

I just started reading into QT but I don't quite get the SIGNAL SLOT functions.
I have a form with 2 QLineEdit and I want to copy the text from the first QLineEdit to the second one when a button is clicked but I don't know how to set up the connect function properly.
I tried tying textChanged function to itself but the result is that the text will edit everytime I press a letter, since that's the signal.
newForm::newForm() {
widget.setupUi(this);
connect(widget.nameEdit, SIGNAL(textChanged(const QString&)),
this, SLOT(textChanged(const QString&)));
connect(widget.pushMe, SIGNAL(pressed()),
this, SLOT(handleButton()));
}
void newForm::handleButton(){
}
I think I have to do something inside the handleButton function but I don't understand how to read and copy the text from the first line since the text() doesn't work inside handleButton
To copy the text from the first QLineEdit called widget.nameEdit to a second one, widget.nameEdit2, when a button is clicked, you can do it with one SIGNAL/SLOT connection using the QLineEdit setText() in a lambda:
connect(widget.pushMe, &QPushButton::released,this, [=](){
widget.nameEdit2.setText(widget.nameEdit.text());
};
You don't need to use the first QLineEdit textChanged() signal, and the above connection copies the whole text available in first field to second filed all at once when you press the button. One the other hand, if you want second QLineEdit to get updated continuously as text changes in first field, then you could use the textchanged() signal of first field , to setText() of second :
connect(widget.nameEdit, &QLineEdit::textChanged,
widget.nameEdit2, &QLineEdit::setText);

Qt5 C++: Custom Spinbox accepting two values

I'm not really into qt but i would like to have spinbox accepting two values
i.e:
It should work like this: select value to change with mouse f.e second value click arrow button and change this value.
Is there any possibility to do that, not creating a new own custom widget?
Short answer is: no
Long answer is:
You should subclass QAbstractSpinBox and implement these two virtual methods:
virtual void stepBy(int steps) override;
virtual StepEnabled stepEnabled() const override;
Keep in mind that you will need to provide your own data store and data manipulation!
The first function determines what happens when the step in either direction is requested. The negative number for steps (that tells how many steps to go in either direction) means go down and positive means up (i.e. clicking on the arrows of the SpinBox). QSpinBox adds the value in steps to its value (so when negative it gets subtracted) for example. Here you can also catch what part of the SpiBox's string the user selected and increment that appropriately with use of
lineEdit()->selectionStart();
lineEdit()->selectedText();
and when you are done you set the correct text back with:
lineEdit()->setText(myModifedValueText); //note that your internally stored value does not need to be QString, you just need to create it from your value in this method to set it to the internal QLineEdit so it can be displayed
The second method is called when the SpinBox needs to know if it can go up or down. So basically here you check the boundaries (if there are any) and return the appropriate flags (QAbstractSpinBox::StepUpEnabled or QAbstractSpinBox::StepDownEnabled or both).
Optinally in the constructor of your SpinBox you can apply QValidator to its internal QLineEdit to accept only certain format of values when the user inputs them by hand, e.g.:
QRegExpValidator *validator = new QRegExpValidator(this);
validator->setRegExp(...); //create a RegExp for your value, you may use any Online regexp validator/creator for this to get the right one
lineEdit()->setValidator(validator);
Finally you can fine-tune your SpinBox to show a text when there is an invalid value or you can fix it yourself using QAbstractSpinBox::fixup and validate the input with the namesake QAbstractSpinBox::validate.
For really pimped out SpinBox you could also re-implement its context menu and actions where you first get the standard menu from QLineEdit:
QMenu *menu = lineEdit()->createStandardContextMenu();
in the QWidget::contextMenuEvent and add/modify it as you need before you show it with menu->exec(event->globalPos()) and then delete menu;.
However QAbstractSpinBox does most of the ground job for you so you really should be fine with implementing just the above two virtual methods.

Saving the content of a QLineEdit object into a string variable (C++)

I've looked around the Qt Documentation, but within my project, I'd like to having most of the non-graphical 'more thinking' part of my program be on a seperate .cpp file.
Given that, I was wanting to take the text typed into a QLineEdit object and save it as a string after the user triggers the 'returnPressed' action, but when I type:
void MainWindow::on_lineEdit_returnPressed()
{
QMessageBox msgBox;
msgBox.setText("The entry has been modified.");
msgBox.exec();
//The line which should save the contents of the QLineEdit box:
string input = QLineEdit::text();
}
...Into the template provided by the Qt Creator IDE (with all necessary slots hopefully created) The compiler returns
In member function 'void MainWindow::on_lineEdit_returnPressed()'
cannot call member function 'QString...'
... and so on.
How should I rewrite my code to do this correctly?
You must choose how to store the string. Your main options are: array of chars, std::string from the standard library, and QString from Qt. If you need to use the string in a third party library then you might need to store it in an std::string or an array of chars, but if that's not the case then I suggest that you simply use QString as it is widely used throughout Qt, although you can convert a QString to std::string or array of chars.
You must actually retrieve the text. To do this you must call the text() function on the QLineEdit instance, not on the QLineEdit class itself. All widgets can be accessed through the ui pointer. Open the designer and check the name of the line edit, the default name is lineEdit, so try replacing the line
string input = QLineEdit::text();
with the line
QString input = ui->lineEdit->text();
How about that:
lineEdit->text().toStdString()
For Qt6 this is the best solution that I found
string input = ui->lineEdit->text().toStdString();
A more developed answer from 'alagner'

Qt sending keyPressEvent

I want to append chars to QLineEdit by sending KeyEvent.
I'm using code like this:
ui.myEdit->setFocus();
for(size_t i = 0; i < 10; ++i) {
QKeyEvent keyPressed(QKeyEvent::KeyPress, 'a', Qt::NoModifier);
QWidget::keyPressEvent(&keyPressed); // or
//QApplication::sendEvent(QApplication::focusWidget(), &keyPressed);
}
Why there is no change in myEdit?
You can change the change the text of QLineEdit simply by :
ui->myEdit->setText(ui->myEdit->text().append("a"));
But if you really want to change it by sending QKeyEvent you can try this :
QKeyEvent * eve1 = new QKeyEvent (QEvent::KeyPress,Qt::Key_A,Qt::NoModifier,"a");
QKeyEvent * eve2 = new QKeyEvent (QEvent::KeyRelease,Qt::Key_A,Qt::NoModifier,"a");
qApp->postEvent((QObject*)ui->myEdit,(QEvent *)eve1);
qApp->postEvent((QObject*)ui->myEdit,(QEvent *)eve2);
Your approach is not wise.
Setting the focus yourself may annoy more than one user which loose focus from one UI element for the other.
By calling keyPressEvent directly you are skipping many layers of processing from the framework. Only misbehavior await down this path.
To reply to
I want to append chars to QLineEdit
You can obtain the line edit text, modify at your will and set it back.
QString currentText = ui.myEdit->text();
QString toappend = "aaaaaaaaaa";
QString nextText = currentText + toappend;
ui.myEdit->setText(nextText);
or one line
ui.myEdit->setText(ui.myEdit->text()+mystring);
Synthesizing a key press event to append characters to a line edit is asking for endless trouble. You'd need to retain the state of the control to ensure that you are in fact appending characters. If the cursor is not at the end, you'll be inserting or prepending characters. If any modifiers are active, you may cause the widget to act as if, say, a clipboard shortcut was activated. Say if you "append" an X while Ctrl/⌘ is held down, you'll cause any selected text to disappear from the line edit.
In other words: if you want to append something to a textedit, simply append it, don't synthesize keystrokes.
lineEdit->setText(lineEdit->text() + "appended");
That's it. To do it properly via appending keystrokes requires about a page of code, and even then it can't but rely on Qt's implementation details.