I am running a Qt program on embedded linux. My program needs to be able to read some information from a text file that is located in the same folder. When I run the program everything works OK.
I now want to make my program start at startup, so I add the line
/home/my_program_name -qws &
to one of the files in the /etc/init.d folder. When I restart my machine, the program runs but it doesn't seem to be able to read the text file. It looks like that folder has not been initialized or read when the program starts.
I should mention that the /etc/init.d folder contains several files that are executed in alphabetic order and that the Qt program is the last one to be executed (i.e. at the end of the last file).
How do I make my program access the text file at startup?
In order to open a file with relative path (e.g. same directory as application), You need to make sure current directory is program's location.
You set current directory to application's directory by using following.
int main(int argc, char *argv[])
{
Q_INIT_RESOURCE(myapplication);
QApplication a(argc, argv);
QDir::setCurrent(qApp->applicationDirPath());
...
or
int main(int argc, char *argv[])
{
Q_INIT_RESOURCE(myapplication);
QApplication a(argc, argv);
QDir::setCurrent(QFileInfo(argv[0]).absoluteDir().absolutePath());
Related
I am totally new to Qt and CMake. I have been doing a google test on my project (cmake and qt) for which I need to test the match of two images. I have a folder (outside the project directory) that contains these images. I want to access these images but not using the absolute path.
Something like this:
imread("home/../../test_images/img1.jpg")
But I want to set a common path for the images folder, so that anybody using my project later on will just have to set their test_image folder path with respect to their machine, and need not make changes in the code.
I have tried the following so far.
1 . Tried adding a .qrc resource file and tried to access the images. (This did not work since the images folder was outside the project directory.)
Tried to set a Path variable in QT build environment settings.
None of the two methods worked.
What I am trying to accomplish: "To be able to avoid using an absolute path for the images I use and allow people trying to implement my code to only change the path at one place with their own test image locations."
Edit:
Looking for a way for setting a variable eg.IMG_PATH = "/path/to/image/files" which can be set once and only the variable is used all over the executable files. So when someone clones my project they will just have to update the IMG_PATH variable with the path to where their image files are located. So that now the IMG_PATH variable gets updated everywhere in the remaining parts of the project.
UPDATE after answer given by #squareskittles :
My project Structure :
Project_Tester
|--CMakeList.txt
|--ExecutableScript.sh.in
|--test
|---CMakeList.txt
|---sample1.cpp
|---sample2.cpp
|---main.cpp
Sample 1,2 are c++ files with different testcases.
The main.cpp runs all tests in the sample.cpp files, as below :
#include "gtest/gtest.h"
int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
According to answer given by #squareskittles , How should i structure my main.cpp ,to be able to use/access the variable "IMAGES_PATH" in the files sample1.cpp and sample2.cpp ?
Is there a way to do it from QT Creator alone than running it from the terminal ?(by modifying .sh file contents)?
Or can the Path be set manually in the ExecutableScript.sh.in file ?
How can I access this variable that is set, from the other cpp files of the project ?
To expand my suggestion, you can use CMake to grab an initial default path from the user configuring and building the project. CMake can grab the path from the command line like this, then use configure_file() to populate an executable start script with the provided path.
Run cmake with the -D option like this to populate a CMake variable called IMAGES_PATH:
cmake -DIMAGES_PATH=/my/path/to/imagefiles ..
Add a configure_file() call to your CMakeLists.txt to generate an executable start script:
...
configure_file(
${CMAKE_SOURCE_DIR}/MyExecutableStartScript.sh.in
${CMAKE_BINARY_DIR}/MyExecutableStartScript.sh #ONLY
)
This call reads in the template file (MyExecutableStartScript.sh.in) and will generate a new MyExecutableStartScript.sh file, replacing the #IMAGES_PATH# variable in your template start script with the actual path to the images. The template file would look something like this:
#!/bin/sh
./MyExecutable "#IMAGES_PATH#"
The populated start script (after running CMake) would be renamed MyExecutableStartScript.sh and contain this:
#!/bin/sh
./MyExecutable "/my/path/to/imagefiles"
A simple C++ executable to read this command line path argument could look something like this:
#include <string>
#include <iostream>
int main(int argc, char ** argv) {
string imagesPath = "";
if( argc == 2 ) {
imagesPath = argv[1];
} else {
std::cout << "Usage: ./MyExecutable /path/to/images" << std::endl;
return 1;
}
...
}
Once the executable is built, the path to your images can easily be changed by modifying the generated start script manually. Most importantly, this example allows you to set a default location once at the beginning, but you also wouldn't require a code re-build to change the image file path.
Define your pictures path in your program settings. Use the QSettings class to store (persist) and retrieve your program settings when needed. You may want to provide your uses with a QDialog to edit your program settings. Here is an example of a portable app doing that.
Hello I am trying to set the QWebEngine URL to an index.html file that is placed in the working directory.
I am trying to use the file by setting the URL to ./index.html but it cant seem to find the file.
Here is where my files are placed
content (Work directory)
main.cpp
content.pro
index.html
How can i open index.html through the QWebEngine without using the full system path?
here is my code
#include <QApplication>
#include <QWebEngineView>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
QWebEngineView view;
view.setUrl(QUrl(QStringLiteral("file:///./index.html")));
view.resize(1024, 750);
view.show();
return app.exec();
}
Try moving the html file to your project build directory (you're currently keeping it inside the source directory). Then you can build your URL this way:
QUrl url = QUrl::fromLocalFile(QDir::currentPath() + "/index.html");
and set it to the view:
QWebEngineView view;
view.setUrl(url);
view.resize(1024, 750);
view.show();
From http://doc.qt.io/qt-5/qurl.html
qDebug() << QUrl("main.qml").isRelative(); // true: no scheme
qDebug() << QUrl("qml/main.qml").isRelative(); // true: no scheme
qDebug() << QUrl("file:main.qml").isRelative(); // false: has "file" scheme
qDebug() << QUrl("file:qml/main.qml").isRelative(); // false: has "file" scheme
Try: view.setUrl(QUrl(QStringLiteral("index.html")));
As p-a-o-l-o pointed out in his answer, you're likely building out-of-source, so your index.html file has to be in the folder where content.exe is created, not in the source folder.
To make this less complicated, and safer, Qt supports embedding files in the .exe via Qt Resource files (.qrc). These can easily be created in Qt Creator, and once added to the project, the embedded files are accessed via a qrc:/// prefix.
So in your sample code, after adding a .qrc file to your project and adding index.html to it, you would adjust your code like this:
view.setUrl(QUrl(QStringLiteral("qrc:///index.html")));
This has the advantage of working regardless of build type or location, and it's a lot simpler than trying to add a file copy step to your project file (or to manually copy the file each time)
I am using the simple browser example and trying to add the flash player from my source folder instead of using the one from my computer.
I have modified the code as per the document
in my main.cpp before creating the QApplication I do the following:
argc = 3;
argv[1] = "--ppapi-flash-path=./PepperFlashPlayer/libpepflashplayer.so";
argv[2] = "--ppapi-flash-version=26.0.0.151";
QApplication app(argc, argv);
QWebEngineSettings::defaultSettings()->setAttribute(QWebEngineSettings::PluginsEnabled, true);
This works fine for Linux and flash loads from my source folder (I made sure of this by removing flash .so file from my linux)
BUT my problem is on mac when I do
argc = 3;
argv[1] = "--ppapi-flash-path=./PepperFlashPlayer/PepperFlashPlayer.plugin";
argv[2] = "--ppapi-flash-version=26.0.0.151";
QApplication app(argc, argv);
QWebEngineSettings::defaultSettings()->setAttribute(QWebEngineSettings::PluginsEnabled, true);
This does not load flash at all - I use this URL to check.
I have both the .plugin and .so in the PepperFlashPlayer folder in my source folder where main.cpp and the .pro files are.
What else do I need to do?
NOTE It does not even load the default flash player located at
/Library/Internet \Plug-Ins/PepperFlashPlayer/PepperFlashPlayer.plugin
I have learned the basics of C++ but I have never used visual studio.
I would like to know why I get popup window that says "Unable to start program" and then lists a file path C:\folder\folder\folder\../../lib/Win32DB/ProjectNameDB.lib. (The message doesn't give me any more info, like 'the system cannot find the file specified' or anything like that.)
ProjectNameDB.lib exists, but not at that particular location. The project builds successfully, and the same path as above appears in the output after TargetPath =.
I have tried setting the project as startup, deleting .suo files and vcproj.user files, starting without debugging, and putting the location of ProjectName.lib in the Output, Library, Include, Reference Directories.
You can not start one *.lib but one *.exe. So build one EXE program you should use the below steps with Visual Statio 2013:
start vs2013;
choose File -> New -> Project;
choose Win32 Console Application, and write your project name, click OK;
click Next, click Finish;
Now, you can write "Hello World" in 'x.cpp'(here 'x' is your project name); the following code:
int main(int argc, _TCHAR* argv[])
{
printf("Hello Wrold!\n");
return 0;
}
save, build and start run it, it will print 'Hello World' in console.
exe file must have main function, but lib file is not necessary.
So... the problem was that the project was configured to run as a static library and not as an executable.
Properties -> Configuration Properties -> General
I'm using boost to create a directory to place some temp files in.
int main( int argc, char* argv[] )
{
std::cout << "Current Dir: " << argv[0] << std::endl;
boost::filesystem::create_directories( "TempFolder" );
return 0;
}
Now if double click the exe, the folder "TempFolder" is created in the same directory as the exe, which I expect. However if I now drag a file onto the exe the folder is created in "C:\Documents and Settings\0xC0DEFACE" which i certainly was not expecting.
Seeing my app hasnt changed, and the dir being printed out hasnt changed, and my app is currently ignoring passed strings, why is the folder now being created in a new directory?
im running windows XP, with VS9 and am using boost 1.39.
I think it's because of the way you 'execute' your binary.
In the first case you double click it and it will run in 'current' directory.
In the second case you drop file on it which causes different action by Windows to execute your binary. In the second case the binary runs in your 'home' directory I believe.
It's the difference between how Windows executes your application.
I've had similar issues when dropping files on my executable.