Saving the content of a QLineEdit object into a string variable (C++) - 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'

Related

How does the string that windows passes into command line argument when I choose to open a file with my application look?

I'm building some kind of a music player and I have a problem with a filename that is being passed into command line argument when I doubleclick it.
The player has a QLabel that shows the name of the song that is playing at the moment, which I get by parsing a filepath to the song that is stored in a QStringList. So when I open files from inside the application via QFileDialog command everything is working fine and I get a correct name, however when I try to open a file via my application from outside of it (e.g. by doubleclicking an mp3 file)
the string I get looks like this (my system language is not chinese), it's different every time as well.
I'm passing the command line argument into my mainWindow class like this:
QString arg;
arg = argv[1];
SoSoMain w(arg); //explicit SoSoMain(QString arg, QWidget *parent = 0);
Then it is added to a QStringList and from there it is accessed by a QLabel through another function that just cuts off everything before the slash and the extension, so I don't see how my code could cause that.
I'd be very grateful if someone could explain me why this happens and how to fix it. Thanks in Avance!
At main first you should do is create instance of QApplication class. You can do this like:
QApplication app(argc, argv);
Then you can get the list of arguments with
app.arguments();
which returns the QStringList with all commandline arguments.
Usually arguments().at(0) is the program name, arguments().at(1) is
the first argument, and arguments().last() is the last argument.
On Windows, the list is built from the argc and argv parameters only
if modified argv/argc parameters are passed to the constructor. In
that case, encoding problems might occur.
Otherwise, the arguments() are constructed from the return value of
GetCommandLine(). As a result of this, the string given by
arguments().at(0) might not be the program name on Windows, depending
on how the application was started.

Why is slot passed as string? Qt

private:
Button *createButton(const QString &text, const char *member);
void abortOperation();
bool calculate(double rightOperand, const QString &pendingOperator);
Button *pointButton = createButton(tr("."), SLOT(pointClicked()));
In qt's calculator example: http://qt-project.org/doc/qt-4.8/widgets-calculator.html
The createButton member function takes two constant string. Then why we are passing slots to them as a second argument?
Simplest summary: The create button function allocates a new button, sets the text, and then connects that button's clicked signal to the slot represented with the string you sent in.
Button *Calculator::createButton(const QString &text, const char *member)
{
Button *button = new Button(text);
//NOTE right here it uses the string you passed in - BEGIN
connect(button, SIGNAL(clicked()), this, member);
//NOTE right here it uses the string you passed in - END
return button;
}
A little bit more detail as to why the signal and slot macros are compatable with strings like this (per this previous stack overflow post):
As Neil said, the SLOT and SIGNAL macros are defined as
> #define SLOT(a) "1"#a
> #define SIGNAL(a) "2"#a
The #a (with # a stringizing operator) will simply
turn whatever is put within the parentheses into a string
literal, to create names from the signatures provided to the macros.
The "1" and "2" are merely there to distinguish between slots and
signals.
This earlier post should provide you some more insight.
If you wonder about the "why?" of all this macro stuff and
preprocessing, I would suggest you read up on the
"Meta-Object-Compiler" or MOC. And just for fun you could have a look
at what MOC does to the code you provide it with. Look through its
output and see what it contains. That should be quite informative.
In short, this preprocessing through MOC allows Qt to implement some
features (like the signals and slots) which C++ does not provide as
standard. (Although there are arguably some implementations of this
concept, not related to Qt, which don't require a Meta Object
Compiler)
Hope that helps.
Please note the post I linked has other links of value, that didn't come through with the copy and paste.

Qt SLOT macro used as function argument

I'm going through the calculator example that was installed with Qt 5.1.1 and there is a private function used to create button widgets (Button inherits QToolButton):
Button *Calculator::createButton(const QString &text, const char *member)
{
Button *button = new Button(text);
connect(button, SIGNAL(clicked()), this, member);
return button;
}
The example calls the above function to create several different buttons e.g.:
createButton(tr("Clear"), SLOT(clear()));
Where void clear() was declared as a private slot. I understand what the code is trying to do but I want to know why does passing SLOT(clear()) as the const char *member work. I can't seem to find much online that would explain using SLOT like that.
As you can see in the documentation of the connect method, the function signature expects the const char* type. These are the corresponding defines from QtCore:
Q_CORE_EXPORT const char *qFlagLocation(const char *method);
...
# define SLOT(a) qFlagLocation("1"#a QLOCATION)
# define SIGNAL(a) qFlagLocation("2"#a QLOCATION)
It is a bit more complex and you can see the details in here, but I simplified it for the sake of the explanation and understanding.
This "old" signal-slot syntax is basically "string" based, and that is also the fundamental flaw with it. This was fixed in Qt 5, however. It is now closer what you seem to imply with your question so that you would rather expect it to be function or method pointers since you eventually pass such an element to the SLOT and SIGNAL moc tokens.
For completeness, the corresponding SIGNAL and SLOT tokens (i.e. Q_SLOTS, Q_SIGNALS, etc) are processed by the meta object compiler, aka. moc, the way that it puts those into the ".moc" files. You can see it yourself if you open those files up. For further details, look into the moc source code which can be found in here.

qt/c++ naming of variables dynamically

I am in the process of developing a html editor in Qt for one of my university assignments, and i am having a problem regarding naming of some variables.
the problem is this:
when the user decides to load their "project" the program iterates through the folder and finds how many .html files are in there, it then creates tabs for them to be displayed in.
I have a custom QTextEdit which has a customer completer and syntax highlighting etc. the problem i am having at the moment is how to create them depending on the number needed.
i create a QStringList of file names:
QStringList m_files;
m_files = aDialog.m_loadDirectory->entryList(QStringList("*.html"),QDir::Files|QDir::NoSymLinks);
then i iterate through each one of the list:
for(int i=0; i<m_files.count();i++)
{
}
and for each one i need to create a new custom QtextEdit
TextEdit *name = new TextEdit;
then add to the tab
tabs->addTab(name,"someTitle");
but as each TextEdit needs to be different for each tab (i think this is correct) i need a different Variable name for each one.
i thought about creating a list/array of TextEdit objects but as i dont know how many i need to use, i could end up easily with too many (wasted memory) or not enough..
any ideas on how i can get around this?
one thought..
would it be possible to create a TextEdit object before the loop
then make a copy of that object in the loop and add the copied object to the tab? (still variable naming problem...)
thanks
but as each TextEdit needs to be different for each tab (I think this is correct)
Yes, you need a different TextEdit in each tab.
I need a different Variable name for each one.
No, you don't need a different variable name for each one. You need different objects, but variable names don't have much to do with that.
A simple:
for (...) {
TextEdit *te = new TextEdit(...);
// set up that text edit in whatever way you need
tabs->addWidget(te, "foo");
}
does exactly what you want. The variable name te is completely irrelevant (it won't even appear in the executable outside of debugging symbols). Each time through the loop, you'll be working on a separate TextEdit instance.
If you need to refer to that TextEdit by name at runtime, you can keep all your widgets in a collection, a QMap for instance.
QMap<QString, QWidget*> all_editors;
...
for (...) {
TextEdit *te = ...;
all_editors[filename] = te;
...
}
You have discarded quickly the only viable solution : put your text edits in a collection. The textedit have to be created with new, so the collection itself will not waste space.
You can use a QPair<QTabWidget*, QTextEdit*> for simplest cases. For more complicated cases create a custom widget, and just make a list of those.
Copying a QObject is a really bad idea. I think the copy constructor is private so you will not even be able to do that

QLineEdit thousand separator

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.