how to make a console cmd for Qt app in Linux? - c++

I made a basic text editor(called 'Note') in Qt on Arch Linux! so I built the project and made an installer using installjammer. now when I type note in terminal it opens the program.
Now here is my question:
if we use nano or leafpad or mousepad it take the path of the file opens it.
Eg. nano /etc/fstab
how can I do this in my program? do I need to edit something in the installer or in my codes? HELP ME! pls!
~Thanks!

You might want to read the docs for QCoreApplication. Especially:
QStringList QCoreApplication::arguments()
Get the filename from this ist, open the file.

Get the passed command line argument either directly in main() from the argv argument, or through QCoreApplication::arguments(). This is well documented and should be rather easy. The tricky part is actually opening the file. For that, you need to schedule a slot for running right after you call exec() on your QApplication instance. First, create a slot. For example, if you're subclassing QApplication, you can:
class MyApplication: public QApplication {
Q_OBJECT
// ...
private slots:
void checkCmdLine();
// ...
};
In your MyApplication::checkCmdLine() function you get the arguments from QCoreApplication::arguments() and check whether a filename was passed. If yes, you open it.
Now you need to make sure that MyApplication::checkCmdLine() will run right after you call exec() on MyApplication. You do that in your main() function by using QMetaObject::invokeMethod(). For example:
int main(int argc, char* argv[])
{
MyApplication* app = new MyApplication(argc, argv);
// ...
QMetaObject::invokeMethod(app, "checkCmdLine", Qt::QueuedConnection);
app->exec();
// ...
}
If you're not subclassing QApplication, then you can implement the slot in some other QObject subclass and use QMetaObject::invokeMethod() on that instead.

Related

QTCreator 5.0.2, parallel run of two window, C++

I went throught suggested "questions" about my problem. However neither does not solve it.
I program two windows. The second window is opening from first window. I need active the both windows, however to start the first window(MainWindow) I use:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.setWindowModality(Qt::NonModal);
return a.exec();
}
As was mentioned, the second window is started from pushButton, which is situated in first window(MainWindow) by same way.
void MainWindow::on_pushButton_2_clicked()
{
Graphics gr;
gr.setWindowModality(Qt::NonModal);
gr.exec();
}
I changed modality to NonModal,however the problem is without change. The Non-Modal mean:"The window is not modal and does not block input to other windows." <- from documentation
By documentation is recommended to avoid used .exec(). The alternatives are .show() and open(), which i tried. After the modification, the second window is shut down immediately after opening. after open immediately shut down.
Do you have any idea, how to solve that?
Graphics gr; defines a local variable, so the object is destructed as soon as it goes out of scope (at the end of your function).
In Qt, the typical approach is to work with pointers to Qt widgets (and, more generally, QObjects), but have a parent for each – the parent will clean it up.
Try this instead:
auto gr = new Graphics(this);
gr->setWindowModality(Qt::NonModal); // this is the default, no need for this call
gr->show();
This way the window will survive until your main window is destructed. In Qt there is also a mechanism for widgets/objects to self-destruct:
this->deleteLater();
So for example if you want to close and cleanup gr you can use that mechanism (you could also store gr as a member and call gr->deleteLater().

Directly executing a batch through clicked function in qt

So I'm trying to have my "button" directly execute a Batch file, important here is that I don't want it to show me a dialogue and make me chose the path, which is the problem I'm having right now with the following code
void MainWindow::on_pushButton_clicked()
{
QString filename=QFileDialog::getOpenFileName(
this,
tr("Open File"),
"C://",
"All files (*.*);;Text File (*.txt);;Music file (*.mp3)");
}
I think this is probably really simple, but i can't get it, I'm not even learning c++ at the moment but my boss asked me to create something out of my scope (wants me to create a GUI for a batch file and have them interact) and I thought of this approach, which is just creating a GUI that executes it.
I've looked at this question: asked to execute an external program with Qt
but they don't talk about how the file path can directly be added into the code, or if I should even be using Qprocess and how, and if I can pass it through "clicked" function.
I'm really inexperienced, all of the code above I got with the help of the internet, but I really don't know how to program using c++
so could someone please be kind enough to show me how a file path can be added to the code, assuming it's in C:\Users\name_goes_here\Downloads
I'd really appreciate it :D
I'd recommend using QProcess for anything "execute external program" with Qt.
You could do it like this:
void MainWindow::on_pushButton_clicked()
{
QProcess process;
process.start("C:/Users/name_goes_here/Downloads/yourfile.bat");
process.waitForFinished(); // Assuming that you do want to wait for it to finish before the code execution resumes
}
Note the "/" in the path. Only Windows uses the messed up "\" for path separation, which would require you to write "C:\\Users\\.." in any string in C++ as "\" needs to be escaped.
Luckily, Qt uses "/" as the universal separator and translates it to whatever the OS needs as required. So you should just use "/" whenever working with Qt.
This is from the Qt documentation:
Qt uses "/" as a universal directory separator in the same way that "/" is used as a path separator in URLs. If you always use "/" as a directory separator, Qt will translate your paths to conform to the underlying operating system.
And finally, if you don't know how to code in C++, shouldn't you be learning that first instead of trying to execute batch files from within a library as complex as Qt? Sounds like you're trying to do too many new things at once.
This is fairly simple merging your source and the one you linked:
void MainWindow::on_pushButton_clicked()
{
QProcess::execute(
QString::fromLatin1(
"cmd.exe /c C:\\Users\\name_goes_here\\Downloads\\file.bat"));
}
Notes:
I used QProcess::execute() instead of QProcess::start() to make things even simpler.
To achieve execution of the batch file, I pass it to cmd32.exe as this is the interpreter which is responsible.
As MCVE testQProcessBatch.cc:
// Qt header:
#include <QtWidgets>
void on_pushButton_clicked()
{
#if 0 // WORKS:
QProcess::execute(
QString::fromUtf8("cmd.exe /c C:\\Users\\Scheff\\Downloads\\testBatch.bat"));
#else // WORKS AS WELL:
QProcess::execute(
QString::fromUtf8("C:\\Users\\Scheff\\Downloads\\testBatch.bat"));
#endif // 0
}
int main(int argc, char **argv)
{
qDebug() << "Version:" << QT_VERSION_STR;
// main application
QApplication app(argc, argv);
QMainWindow qWin;
QPushButton qBtn(QString::fromLatin1("Start cmd"));
qWin.setCentralWidget(&qBtn);
qWin.show();
QObject::connect(&qBtn, &QPushButton::clicked,
&on_pushButton_clicked);
// run application
return app.exec();
}
and the test batch file testBatch.bat:
echo "This is testBatch.bat"
pause
Tested with VS2013 on Windows 10:
Thanks for contributing guys!
I tried using the QProcess method but I think I'm too inexperienced when it comes to figuring out problems associated with it (which I did face when using this method). the CMD route is probably good but I also thought it was too difficult and both of these methods didn't work for me.
Here's what I have now (thanks to Detonar and ymoreau) and and it seems to be doing the job, this might not be the most optimal approach, but it worked for me!
I included QDesktopServices and QUrl
void MainWindow::on_pushButton_clicked()
{
QString filename="C:\\Users\\Name_goes_here\\Downloads\\test.bat";(
this);
hide(); //optional
QDesktopServices::openUrl(QUrl("file:///"+filename,QUrl::TolerantMode));
}

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.

Can't update Text Edit Text QT

I'm having an issue. My textEditBox doesn't seem to be updating when my Addtext function is called.
Here's my Addtext:
void CTextBox::AddText(QString string, QString spriteString)
{
textBrowser->setText(string + spriteString);
update();
}
Another class then calls the function and it should add text to the textbox but it doesn't.
How do you call CTextBox::AddText()? update() only schedules a paintEvent() for later, when the program returns to the event loop. That means that
you actually need to have an event loop, ie. at some point you need to call qApp->exec();
you need to allow the programm some time to qApp->processEvents() (insert that after update()), if you want any paining done within a blocking while() {...} or something like that.
Edit: Come to think of it, you shouldn't even need to call update() nor processEvents() if your program returns to the event loop some time after AddText, so there really seems to be an issue with the event loop. Post your main.cpp, will you?
Here is a trivial example of what it sounds like you are trying to do. Maybe you can see where your design differs?
Notice: no explicit update() is needed. I think that's a red herring. I think it far more likely that (1) you are somehow calling your AddText method with empty strings, or (2) your real text edit is a different variable, and have somehow created two of them and are updating one that just exists in memory and was never added to a layout. Perhaps the code of your FileLoaderQT would help? (You can edit your question rather than posting in comments.)
#include <QtGui>
int main(int argc, char **argv) {
QApplication app(argc, argv);
QMainWindow w;
QTextEdit *edit = new QTextEdit;
w.setCentralWidget(edit);
edit->setText("Hello world!");
w.show();
edit->append("Hello world again!");
return app.exec();
}

Qt doesn't find QStackedWidgets' slot setCurrentWidget

I am writing a wizard-style application in Qt that uses a QStackedWidget to organize the individual pages of the wizard. Now I want to switch between the pages, which should be possible using the function setCurrentWidget(...):
I have a simple main class that instantiates a QWidget audioconfig. Then, it adds this QWidget to a QStackedWidget pageStack using pageStack.addWidget(&audioconfig);.
Later, I want to connect a certain signal from a different QWidget hub to setCurrentWidget(...) of the QStackedWidget in order to switch the page. However, my compiler remarks that
0Object::connect: No such slot QStackedWidget::setCurrentWidget(audioconfig) in /Users/paperflyer/Development/App/main.cpp:41`
There are two things I don't get here:
there clearly is such a function. You can look it up in the class definition of QStackedWidget. What is going on here?
Why is the first character of the compiler output a '0', while my source code clearly and correctly shows it as 'Q'?
Here is the whole code:
int main(int argc, char *argv[])
{
QApplication app(argc,argv);
QStackedWidget pageStack;
CHub hub; // inherits from CWidget
CAudioConfig audioconfig; // ditto
pageStack.addWidget(&hub);
pageStack.addWidget(&audioconfig);
// connect() is a custom signal of hub
QObject::connect(&hub, SIGNAL(configure()), &pageStack, SLOT(setCurrentWidget(&audioconfig)));
pageStack.setGeometry(100,100,700,500);
pageStack.show();
return app.exec();
}
As always, thank you so much for your help!
QObject::connect(&hub, SIGNAL(configure()), &pageStack, SLOT(setCurrentWidget(&audioconfig)));
When you connect a signal to a signal/slot, you connect a signature. The actual parameters are passed when emitting the signal. The above should probably be setCurrentWidget(QWidget*), but even so it won't work, because the signature for the signal must match the one of the slot.
Note: I think that if the signal has more parameters than the slot it will still work, provided that the first parameters are the same.
Your connect line is wrong. It should be:
// connect() is a custom signal of hub
QObject::connect(
&hub, SIGNAL(configure()),
&pageStack, SLOT(setCurrentWidget(QWidget *))); // <- change here
You connect based on the prototype of the slot and/or signal.