Save the screenshot of a widget - qt

I want to save a screenshot of a widget in Qt.
I created the following code that should work:
QWidget* activeWidget = getActiveWidget();//a function that returns the current widget.
if (activeWidget == NULL)
{
return;
}
QPixmap screenshot;
screenshot = QPixmap::grabWidget(activeWidget,activeWidget->rect());
if(screenshot.isNull()){
printf("ERROR");
}
bool a= screenshot.save("c:\\temp\\asd.jpg", "JPG", 50);
But unfortunately this does not seem to work.
Does anyone know what the problem is?

In this answer and this forum post, people suggest the following:
Most likely, the plugin which is required to handle .jpg files is not found by your application. In order to resolve this issue, do one of the following things:
If you are doing a static build, add QTPLUGIN += qjpeg to your .pro file or
if you are doing a dynamic build, put the imageformats folder from %QTDIR%\plugins next to your .exe

Related

Pre-compile QML files under Qt Quick Controls

I am importing 2 QML files that come with Qt Controls - ScrollBar.qml and Button.qml in my project. I pre-compile all .qml files that I wrote to reduce application launch time. Is there a way to pre-compile these 2 QML files that come as part of the package?
I tried to remove these files from the qml/QtQuick/Controls/ path and placed them in the same folder as my .qml files but it still failed to load. When I reference ScrollBar in my code, it always tries to load ScrollBar.qml from qml/QtQuick/Controls/ path.
Does any one know if it is possible to pre-compile these QMLs at all? If yes, has any one successfully done it?
Appreciate any help. Thank you.
I'm assuming that you're referring to the Qt Quick Compiler as pre-compiling. The simplest way would just be to build the entire Qt Quick Controls module with the Qt Quick Compiler.
If you need to have it within your project, you could try adding an import that contains the Qt Quick Controls import. QQmlEngine::addImportPath() says:
The newly added path will be first in the importPathList().
That statement seems to imply that order matters, and the code confirms it:
QStringList localImportPaths = database->importPathList(QQmlImportDatabase::Local);
// Search local import paths for a matching version
const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(uri, localImportPaths, vmaj, vmin);
for (const QString &qmldirPath : qmlDirPaths) {
QString absoluteFilePath = typeLoader.absoluteFilePath(qmldirPath);
if (!absoluteFilePath.isEmpty()) {
QString url;
const QStringRef absolutePath = absoluteFilePath.leftRef(absoluteFilePath.lastIndexOf(Slash) + 1);
if (absolutePath.at(0) == Colon)
url = QLatin1String("qrc://") + absolutePath.mid(1);
else
url = QUrl::fromLocalFile(absolutePath.toString()).toString();
QQmlImportDatabase::QmldirCache *cache = new QQmlImportDatabase::QmldirCache;
cache->versionMajor = vmaj;
cache->versionMinor = vmin;
cache->qmldirFilePath = absoluteFilePath;
cache->qmldirPathUrl = url;
cache->next = cacheHead;
database->qmldirCache.insert(uri, cache);
*outQmldirFilePath = absoluteFilePath;
*outQmldirPathUrl = url;
return true;
}
}
Your project structure might look something like this:
myproject/
qml/
main.qml
QtQuick/
Controls/
Button.qml
ScrollBar.qml
qmldir
In main.cpp you'd set the path to the qml directory (note that the path will be different depending on whether you're doing an in-source build or a shadow build of your project, so you may want to use a resource file to simplify things):
engine.addImportPath("path/to/qml");
Note that the controls import other types. For example, Button uses the Settings singleton, which comes from the QtQuick.Controls.Private import, so you'd need to copy that into the qml directory, too. Settings loads a certain style for the button (ButtonStyle), which could be any of the styles in this folder, depending on which style is in use.
In short, you need to copy all of the potential dependencies of the QML files you're using.

QFileDialog View Files and Folders when choosing a Directory

I'm new to learning the Qt library, and I'm having a hard time getting QFileDialog to work properly. I want the user to be able to select a directory but also be able to view the files and folders so they know which directory they should pick. I have seen things similar to this being posted elsewhere but everything I've tried hasn't made any difference in the output.
I've tried creating my own dialog and setting the mode to directory, which says that it should display both files and folders:
QFileDialog myDialog(this);
myFileExplorer.setFileMode(QFileDialog::Directory);
myFileExplorer.setDirectory("C:/");
QString file = myFileExplorer.exec();
And I've tried using getExistingDirectory as well, but with that function it always only shows the directory as well.
Thanks
QString getExistingDirectory ( QWidget * parent = 0, const QString & caption = QString(),
const QString & dir = QString(), Options options = ShowDirsOnly )
The default options parameter is set to show dirs only, you have to change it to
QFileDialog::DontUseNativeDialog
But unfortunately you won't be able to use native dialog.

Load Animated gif file using QMovie in Ubuntu

I am new to Ubuntu & Qt. I need to show busy status for other long operations. So, I was just trying to use waiting animation gif files to load instead using Progress bars.
I am using Eclipse Editor for Qt project.
Trolltech/../imageformat folder contains libqgif.so and libqgif.so.debug. I have copied these files in my debug folder too.
loader.gif is added in qrc file and kept in /Resources folder
IN MainWindow class I have added label and after setupUi(this) been called I call my ShowMovie() function as below:
ShowMovie() {
QMovie *movie = NULL;
movie = new QMovie(":/Resources/loader.gif");
if(movie->isValid()) {
ui.label_3->setMovie(movie);
movie->start();
}
else
qDebug()<<"Movie is Invalid";
qDebug()<<QImageReader::supportedImageFormats ();
}
Always isValid() function returns false & I got message that Movie is Invalid.
Last qDebug() returns
("bmp", "gif", "ico", "jpeg", "jpg", "mng", "pbm", "pgm", "png", "ppm",
"svg", "svgz", "tif", "tiff", "xbm", "xpm")
i.e means gif support is available.
I have tried to call ShowMovie() function before loading Main UI and/or on button clicked. Both fails.
Provide help on what is to be corrected.
Thank you.
you don't need to copy librairies files *.so.
Try creating the movie object with the full path to loader.gif. Does it work?
Then you have not setup correctly your resource system.
Either you have a syntax mistake in the qrc file which need to be fixed or you forgot to add it as a resource in the project file (.pro) using
RESOURCES = myqresource.qrc

Strange error with QListWidgetItem that uses QIcon

I am building up a QListWidget, browsing through a directory so that every ".png" gets listed with a preview icon.
The core of my populating loop looks like this:
new QListWidgetItem( QIcon(act_fullname), act_filename);
Right after the whole list is ready, the app crashes.
The error is many times repeated and says this:
On Mac OS X, you might be loading two sets of Qt binaries into the
same process. Check that all plugins are compiled against the right Qt
binaries. Export DYLD_PRINT_LIBRARIES=1 and check that only one set of
binaries are being loaded. QObject::moveToThread: Current thread
(0x103339cb0) is not the object's thread (0x10a848670). Cannot move to
target thread (0x103339cb0)
On Mac OS X, you might be loading two sets of Qt binaries into the
same process. Check that all plugins are compiled against the right Qt
binaries. Export DYLD_PRINT_LIBRARIES=1 and check that only one set of
binaries are being loaded.
Do you have any ideas?
Thanks for your help!
EDIT:
If I skip the icons there is no problem. I have also tried going
QListWidgetItem *item = new QListWidgetItem(act_filename);
ui->listWidget->addItem(item);
item->setIcon(QIcon(act_fullname));
and got no difference.
EDIT 2:
I do not call QObject::moveToThread(QThread*) I don't even use threads (deliberately at least).
Also, the errors appear to come after the loop. I have cout-ed every iteration and the end of the loop and right after my "end loop cout msg" I see that
objc[56963]: Class QCocoaColorPanelDelegate is implemented in both
/Users/Barnabas/QtSDK/Desktop/Qt/4.8.1/gcc/lib/QtGui.framework/Versions/4/QtGui
and
/Users/Barnabas/Programming/Qt/demo_OpenCV-build-desktop-Desktop_Qt_4_8_1_for_GCC__Qt_SDK__Release/demo_OpenCV.app/Contents/MacOS/../Frameworks/QtGui.framework/Versions/4/QtGui.
One of the two will be used. Which one is undefined.
Here, too, I do not use QCocoaColorPanelDelegate. I don't even know what it is ... :(
But here is my more detailed code:
boost::filesystem::path p("/path/to/dir");
if(boost::filesystem::is_directory(p))
{
for(boost::filesystem::directory_iterator it(p); it!=boost::filesystem::directory_iterator(); ++it)
{
if(it->path().extension().string()==".png")
{
std::cout<< it->path() <<std::endl;
QString item_name( it->path.stem().c_str() );
QString screen_file( it->path.c_str() );
QListWidgetItem *item = new QListWidgetItem(item_name);
QIcon *icon = new QIcon(screen_file);
item->setIcon(*icon); // if I comment this one out, everything is fine.
ui->imageList->addItem(item);
}
}
}
I have also tested it with a single .png and the image was displayed properly in the list but crash followed with the very same messages.
I have finally found the solution: manually removed the Debug and the Release directories.
For those whose similar problem is not solved by this see: this link.

Qt QFileSystemWatcher on Windows

I have the following issue: I create a QFileSystemWatcher and it runs and works nicely on Linux, but no way on Windows 7. Can you spot anything in the code that might make it not to work?
Thx.
Here is the code to initialize it:
mConfigChangeWatcher = new QFileSystemWatcher();
mConfigChangeWatcher->addPath(config_file_name);
QObject::connect(mConfigChangeWatcher,
SIGNAL(fileChanged(QString)),
this,
SLOT(configFileChanged(QString)));
and this is supposed to be the slot getting the work done:
void MyClass::configFileChanged(const QString &file)
{
qDebug() << "Changed: " << file ;
}
When you check if the file is added to the watcher using QFileSystemWatcher::files() method after the first modification in the file do you get the correct list?
I was with the issue that some applications, when modifing a file, delete the old file from the system and write it again.
Note that QFileSystemWatcher stops monitoring files once they have been renamed or removed from disk, and directories once they have been removed from disk.
I was using QFileSystemWatcher to watch an image file edited by Photoshop. Somehow the file gets removed from the list of files being watched.
I had the same problem and solved it very fast.
Within the slot that manages the fileChanged signal I noted the path disappears from files(). I simply make a check and re-add it if necessary
if (! watcher_.files().contains(path))
{
watcher_.addPath(path);
}
I hope this helps
Fabio

Resources