Why doesn't setting the pixmap of a QLabel work? - qt

I've created a subclass of QLabel that I intend to use in a QGraphicsView. It serves as a movable "point" that one can click on and drag around the graphics view.
Creating the custom class and having it displayed in the graphics view hasn't been an issue; however, trying to get the custom QLabel to paint itself with the image I want isn't happening. The constructor for my custom QLabel class is like so:
TrackerPoint::TrackerPoint(QWidget *parent) :
QLabel(parent)
{
this->setFixedSize( 40, 40 );
QPixmap pixmap( ":/images/target.png" );
this->setPixmap( pixmap );
this->setMask( pixmap.mask() );
}
I've ensured that the images directory exists in the working directory that the application is run from. If it is relevant at all, my QRC file is like so:
<RCC>
<qresource prefix="/images">
<file>images/target.png</file>
</qresource>
</RCC>
I've been trying to deal with this problem for days -- any ideas as to why the image isn't appearing would be lovely. (Does it have to do with the fact that I'm setting a pixmap in the constructor of the QLabel?)

You have:
<qresource prefix="/images">
<file>images/target.png</file>
</qresource>
I think that this will result in a double images in the resource path, i.e. :/images/images/target.png. To fix that, either remove the prefix="/images" or put alias="target.png" in the file tag.
To make it clearer where the error is, you could write your code so that it uses QPixmap::load, since that can be checked for errors:
QPixmap pixmap;
if (!pixmap.load( ":/images/target.png" )) {
qWarning("Failed to load images/target.png");
}
this->setPixmap( pixmap );
Or you could go even further and use QImageReader which can give detailed error messages.

Related

Qt Quick Controls 2 hangs when overwriting Button.qml

I'm trying to implement my own style and for this I want to override the built-in objects. Here's what I'm doing:
// main.cpp
QQuickStyle::setStyle("mystyle");
and
// mystyle/Button.qml
import QtQuick 2.5
import QtQuick.Controls 2.1 as Controls
Controls.Button {
background: Rectangle {
color: "green"
}
}
and
// qml.qrc
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>mystyle/CheckBox.qml</file>
</qresource>
</RCC>
According to the docs I believe this should work automagically using file selectors.
However, my app hangs on startup. My guess is that I fall into a recursive import. How do I do this correctly?
The Qt Quick Controls 2 styling system is based on QML type registration. When you run your app with mystyle, the type known as QtQuick.Controls.Button IS mystyle/Button.qml. Therefore mystyle/Button.qml cannot inherit QtQuick.Controls.Button. It cannot inherit itself.
This is basically the same as writing the following C++:
// button.h
#include "button.h"
class Button : public Button {};
A bit radicalized, but easy to understand analogy. :)
What you can do is to have (My)Button.qml somewhere, let it inherit QtQuick.Controls.Button, and don't register it as a Qt Quick Controls 2 but simply import the folder. This is what we call as "Customizing Qt Quick Controls 2".
The style must be configured before loading QML that imports Qt Quick Controls.It is not possible to change the style after the QML types have been registered. setStyle()
Apply the existing style in your custom style's qml files.
Note: It is recommended to use QQmlApplicationEngine, which internally creates a QQmlFileSelector instance. This is all that is needed to take QML file selectors into use.
See: Creating Custom Styles

How to build widgets from any .ui files created by QtDesigner

I would like to make something like GUI creator which takes an ui file and creates widgets in it, and show in a window.
So I have created a button on click I use QFileDialog to get a file.
And then I would like to use the ui file from QFileDialog to create that gui/widgets and show in a window.
I have tried QFormbuilder, but it always gives me compile error “undefined reference to `QFormBuilder::QFormBuilder()’”
Is there a way to do it in qt5?
Any help appreciated
From documentation of QUiLoader:
QUiLoader loader;
QFile file(":/forms/myform.ui");
file.open(QFile::ReadOnly);
QWidget *myWidget = loader.load(&file, this);
file.close();
I have solved the problem.
Actually I was missing QFormbuilder module in my .pro file. So I have just added them, and it is working fine.

qt layout()->setSizeConstraint

I have a problem with the layout () in Qt 5.
I want to make a dynamic variable dialog.
![enter image description here][1]
Below is the code for the constructor:
SortDialog :: SortDialog (QWidget * parent)
     : QDialog (parent)
{
     setupUi (this);
     SecondaryGroupBox-> hide ();
     TertiaryGroupBox-> hide ();
     layout () -> setSizeConstraint (QLayout :: SetFixedSize);
     setColumnRange ('A', 'Z');
}
The project is built successfully, but when you start receiving a signal from the operating system.
Signal: SIGSEGV
Purpose: Segmentation fault
If you delete a row
layout () -> setSizeConstraint (QLayout :: SetFixedSize);
The program works.
Please, help me.
P.s.:This is an example from the book c++ GUI Programmming with Qt 4 (page 31)
I was having the same problem.
I just solved it.
Probably you don't want the answer after two years, but I really want to write about this somewhere, because there is nothing about this little issue on the web.
The problem was that Qt Designer didn't generate code to set dialog's layout.
I just opened ui_sortdialog.h and found that out of SortDialog a widget was created. Than with this widget a layout would be created. The layout is called gridLayout_4, and every widget and layout of the form are added to this one. When I added to function retranslateUi line SortDialog->setLayout(gridLayout_4); everything worked. Generated code created layout and did everything what needed to be done, but it left SortDialog without any reference to the layout, therefore layout() returned zero.
That's because you didn't create a layout.
Go back to designer and click the form and choose lay out in grid.
If you don't do this, the layout would be 0 and the program will crash.
You have to create a layout, like QVBoxLayout.
QVBoxLayout *layout = new QVBoxLayout;
layout->setSizeConstraint (QLayout :: SetFixedSize);
setLayout(layout);
I fixed this with changing in Designer Form. Make sure that the layout in the Qt Designer is good. Especially "Form -> Adjust Size" at the end. (in the book page 33; creating a "Form-> Lay Out in a Grid"). Use the original code from the book.

Which qt widget should I use for message display?

The QStatusBar has just one line each time and I cannot track the history or save the history in a log file.
So I want to have a dock widget in my mainwindow that is able to display the messages I need in a multi-line way and auto-scrolling way and then automatically saved to a log file.
My question is how to do this in Qt?
If what you are looking for is something similar to the "Application Output" pane of QtCreator, then a simple QPlainTextEdit can do the job. You can call QPlainTextEdit::setReadOnly(true) if you don't want the user to be able to edit its content (i.e. only your application can write to it).
If you want auto-scrolling and automatically saving to a log file, you will need to subclass it though. Here's a little something to get you started:
#include <QCoreApplication>
class MyLogWindow : public QPlainTextEdit
{
Q_OBJECT
/* snip */
public:
void appendMessage(const QString& text);
private:
QFile m_logFile;
};
void MyLogWindow::appendMessage(const QString& text)
{
this->appendPlainText(text); // Adds the message to the widget
this->verticalScrollBar()->setValue(this->verticalScrollBar()->maximum()); // Scrolls to the bottom
m_logFile.write(text); // Logs to file
// optional if you want to see the changes
// after appendPlainText() immediately
// useful if you use this->appendMessage() in a loop
QCoreApplication::processEvents();
}
I leave it to you to deal with the boilerplate (opening and closing the file, dealing with newlines, etc.).
Now, simply put an instance of MyLogWindow in a dock in your QMainWindow, and call MyLogWindow::appendMessage() every time you need to log something to have it displayed, scrolled and saved automatically.

How to display embedded html in Qt WebView

I am trying to get the Qt WebView to display an html file that is embedded as a Qt resource, but I can't seem to get it to work. I created a new Qt Quick application and added a simple qml file:
import QtQuick 2.0
import QtWebKit 3.0
Rectangle {
id: content
width: 800
height: 600
color: "black"
WebView {
id: webView
anchors.fill: parent
url: "qrc:/res/test.html"
}
}
I then created (using the Designer) a resource file that looks like this:
<RCC>
<qresource prefix="/res">
<file>test.html</file>
</qresource>
</RCC>
and created a simple test.html file (in the same directory as the .qrc file):
<html>
<head><title>Hello</title></head>
<body>
<h1>Hello World!</h1>
</body>
</html>
The result is just a blank white window. If I use a regular url (http://www.stackoverflow.com) in the qml file as the url it works - the page is displayed. If I use the name of an embedded image (qrc:/qt-project.org/mac/cursors/images/pluscursor.png) that image is displayed.
It looks to me as if the html file is indeed added (it is at least listed when I enumerate the embedded resources), but my understanding of the Qt resource system is limited, so I may very well have misunderstood something fundamental.
Can anyone tell me what I am doing wrong?
Update: I have verified that the behavior is the same if I attempt to tell the web view to load the url from C++ as well. I have also verified that the resource is indeed embedded - I can open and read the resource using a QResource. Also, this does not appear to be specific to Qt5: http://qt-project.org/forums/viewthread/18181 (someone having a similar problem with Qt 4.8).
First , make sure that resource file is compiled correctly on compile folder (a .RCC file or a qrc_<Resource name>.cpp)
Second, make sure your file path is correct (in my case qrc:/images/resource/html/test.html). You can open QRC file and right-click on html file and then click on Copy Resource Path to Clipboard.
Third, Note that some urls needs more time for loading completely.
Finally, I test this scenario and it works very well (Using Qt 5.1.0)
Good luck - S.M.Mousavi
I don't thing it's possible opening resource from qrc directly in WebView (I've tried all url variants). What I'm doing now is copying the file to the local temp directory and then opening.
QString helpHTMLFile = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
helpHTMLFile.append(QDir::separator());
helpHTMLFile.append("software_manual.html");
QFile(helpHTMLFile).remove();
QFile(":/software_manual.html").copy(helpHTMLFile);
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("pathToFile", "file:///"+helpHTMLFile);
Then QML looks like:
WebView {
anchors.fill: parent
url: pathToFile
}
Ok, here's how I ended up solving this. I ended up using a plain widget instead of a qml based interface.
I then had to read the first html page out from the resources manually and provide the base url. After that, subsequent pages and resources that are embedded as resources load fine.
Here's the code in question:
QResource res(":/html/index.html");
ui->webView->setHtml(reinterpret_cast<const char *>(res.data()), QUrl("qrc:/html/"));
where webView is a QWebView. My .qrc file looks like this:
<RCC>
<qresource prefix="/">
<file>html/index.html</file>
</qresource>
</RCC>
This works in Qt 5.5.0.
The quickest way to load a resource file is using XMLHttpRequest and loadHtml().
This works in Qt 5.10.1 for mobile platforms.
import QtQuick 2.10
import QtQuick.Controls 2.3
import QtWebView 1.1
Page {
anchors.fill: parent
WebView {
id: webView
anchors.fill: parent
Component.onCompleted: {
var resource = 'qrc:/path/to/your/resource.html';
var xhr = new XMLHttpRequest;
xhr.open('GET', resource);
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
var response = xhr.responseText;
webView.loadHtml(response);
}
};
xhr.send();
}
}
}
why not just use
url: "res/test.html"
instead of
url: "qrc:/res/test.html"
?
Then you would not need to use any resource files
Embedded resources URLs loading support by web engine is available in latest Qt at least for WebEngineView in QML. I was not able to find official documentation about this, but one official sample loads page from resources:
WebEngineView {
url: "qrc:/index.html"
...
}
It works for me with Qt 5.8.0 as well.
You can put below line just after QApplication a(argc, argv);
QtWebView::initialize();
Just use Path-To-File & If you saved it in project directory, just set name of file
url: "/res/test.html"
& if file is in project directory
url: "test.html"

Resources