I have made a simple notepad editor using Qt that I try to open with:
p = subprocess.Popen(["myNotepadApp.exe", "myFile.py"])
this opens my app but not with the specified file myFile.py open. Is there any changes I need to make to my Qt code for my Qt open function? Does opening files with this subprocess.Popen() function even call my Qt open function?
void objectDetector::on_actionOpen_triggered()
{
QString fileName = QFileDialog::getOpenFileName(this, "Open file");
QFile file(fileName);
currentFile = fileName;
if(!file.open(QIODevice::ReadOnly| QFile::Text)){
QMessageBox::warning(this, "Warning", "Cannot open file : " + file.errorString());
return;
}
setWindowTitle("Object Editor");
QTextStream in(&file);
QString text = in.readAll();
ui->textEdit->setText(text);
file.close();
}
Here is the constructor of the UI object if it is releveant
objectDetector::objectDetector(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::objectDetector)
{
setWindowTitle("Object Editor");
ui->setupUi(this);
this->setCentralWidget(ui->textEdit);
}
Here is the current main.cpp:
#include "objectdetector.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
auto* od = new objectDetector(&a);
is left in here is for us.
const auto args = a.arguments();
if (args.size() > 1)
{
const auto fileName = args[1];
// Pass the first arg to objectDetector as file name to open it
od->openFile(fileName);
}
return a.exec();
}
What your call to Popen
does is about the same as if you type the following into your shell:
myNotepadApp.exe myFile.py
So, "myFile.py" is passed as an argument to your executable but it fails to do anything with it. The functionality is missing from your Qt application and the whole issue is unrelated to Python's Popen
.
In C++ (like in C), you can access these arguments in main()
using argc
, or the count of arguments and argv
, the vector of arguments themselves. Qt also processes arguments for some Qt-specific flags and offers QCoreApplication::arguments()
as a convenient way to access them.
As you did not share your main.cpp
, I'll have to guess what it looks like. In order to make it work, you'll need to do something like the following:
int main(int argc, char** argv)
{
// Pass argc and argv to QApplication
QApplication app(argc, argv);
// Create your classes
objectDetector od;
// Get arguments back from QApplication
// Qt will have stripped argv of all Qt-specific flags so whatever is left in here is for us.
const auto args = app.arguments();
if (args.size() > 1)
{
// args[0] is the name of your executable, we don't want that
const auto fileName = args[1];
// Pass the first arg to objectDetector as file name to open it
od.openFile(fileName);
}
od.show();
return app.exec();
}
And you will have to give your class objectDetector
a method to handle a file name. Luckily you already wrote all the code we need:
void objectDetector::on_actionOpen_triggered()
{
QString fileName = QFileDialog::getOpenFileName(this, "Open file");
openFile(fileName);
}
// This needs to be public
void objectDetector::openFile(const QString& fileName)
{
// Looks familiar? It's your own code extracted as a method
QFile file(fileName);
currentFile = fileName;
if(!file.open(QIODevice::ReadOnly| QFile::Text)){
QMessageBox::warning(this, "Warning", "Cannot open file : " + file.errorString());
return;
}
setWindowTitle("Object Editor");
QTextStream in(&file);
QString text = in.readAll();
ui->textEdit->setText(text);
file.close();
}
This way, the first argument will be treated as a file name and your application will attempt to open it.
There's room for improvement, however. It will not handle multiple file names and passing a string that does not name a file will result in a "Cannot open file" message box. For anything more complex than getting the first argument, consider setting up QCommandLineParser.
Qt features an example text editor. This seems to do largely what you are trying to accomplish. It's using a QCommandLineParser
. You may be able to get inspiration from there.