0

I've found this example of how to display a QWidget (specifically a QLabel) inside a QML document:

https://kunalmaemo.blogspot.com/2011/07/how-to-display-qwidget-into-qml.html

The problem is that this uses QtQuick 1 and won't compile in my application (which is using QtQuick 2).

How can I do this using QtQuick 2? I need to do exactly what this original sample does: create a QLabel on the c++ side and embed it in a QML document.

Here is what I've been able to do so far. This is similar to the example I posted above, except there is no QGraphicsProxyWidget* mProxy; since it doesn't compile in QtQuick 2, and I made this a QQuickView instead of a QDeclarativeItem for the same reason. On the c++ side I've defined a class named QmlLabel.

Header:

class QmlLabel : public QQuickView
{
    Q_OBJECT
    Q_PROPERTY(QString text READ text WRITE setText)
public:
    explicit QmlLabel(QQuickView *parent = 0);
    ~QmlLabel();

public slots:

    void setText(const QString& text);
    QString text() const;

private:

    QLabel* mLabel;

};

Implementation:

QmlLabel::QmlLabel(QQuickView *parent) :
    QQuickView(parent)

{
    mLabel = new QLabel(QString(""));
    mLabel->setText("Your mother sews socks");
    mLabel->setStyleSheet("QLabel { background-color : red; color : 
        blue; white-space : pre-wrap; }");
}

QmlLabel::~QmlLabel()
{
    delete mLabel;
}

void QmlLabel::setText(const QString& text)
{
    mLabel->setText(text);
}

QString QmlLabel::text() const
{
    return mLabel->text();
}

I'm calling qmlRegisterType for this class, and this allows me to declare an object of type QmlLabel in my QML file like so:

QmlLabel {
    id: whatever
    height: 50
    width: 200
}

Everything compiles, builds and runs, but the QmlLabel is not visible at all. Obviously there is no code in the constructor that actually adds the created QLabel to anything, so even though the label is created successfully it would not be visible without being added to anything. This line in the original example:

mProxy = new QGraphicsProxyWidget(this);
mProxy->setWidget(mLabel);

... is presumably why the label shows up, but I can't call this without QGraphicsProxyWidget to add it to.

So how can I make this work?

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
MusiGenesis
  • 74,184
  • 40
  • 190
  • 334
  • Currently you can not, QQuickView is a widget that provides to show the qml in a QWidget based window, not the other way around. Before, QML was based on QGraphicsView and QGraphicsScene but it has been migrated for years. – eyllanesc Aug 23 '18 at 00:13
  • read https://forum.qt.io/topic/63057/using-a-qt-5-widget-within-a-qml-application/4 – eyllanesc Aug 23 '18 at 00:20
  • Possible duplicate of [How to integrate QWidget in QML (Qt Quick 2.0)](https://stackoverflow.com/questions/24735163/how-to-integrate-qwidget-in-qml-qt-quick-2-0) – eyllanesc Aug 23 '18 at 00:22
  • @eyllanesc Wow, I'm really in a bind then. I was trying to use a `QLabel` instead of a QtQuick.Controls Label because you can set the stylesheet to `white-space : pre-wrap` and I need to be able to render text that has multiple spaces without them all being compressed into a single space as HTML renderers usually do. Is there any way to do this with a Label, or will I need to use a webview for this? – MusiGenesis Aug 23 '18 at 00:28
  • you could create your own Item using QDocument to draw and maybe support it, why do not you use HTML? – eyllanesc Aug 23 '18 at 00:30
  • @eyllanesc I don't follow you - I *am* using HTML. My problem is that I need to display an HTML string (mostly just text but including a few HTML tags like etc.) inside a Label (or *something*) in my QML file. Everything I have in place is working EXCEPT that the Label does not preserve multiple consecutive spaces (but instead compresses the multiple spaces as does any HTML renderer with white-space : normal set). I am only trying to get a `QLabel` working instead because you can set its stylesheet to `white-space : pre-wrap`. – MusiGenesis Aug 23 '18 at 00:35
  • @eyllanesc My app is still using Qt 5.6, so in theory I could still use Qt Quick 1? My problem is that my project does not appear to use a qmake .pro file so there's nowhere for me to set QT += declarative. – MusiGenesis Aug 23 '18 at 00:38
  • Well, that's another thing, I use qmake so I do not know how to do it, maybe that's a question that has already been asked (or you have a search) or should you do it. – eyllanesc Aug 23 '18 at 00:42
  • 1
    Trying to embed a widget to do that seems like an overkill solution, even if it was possible. Try replacing the spaces with non breaking spaces ( ). – GrecKo Aug 23 '18 at 07:32
  • @GrecKo I agree it's overkill but no choice here.   is rendered as " " in a Label, which only supports a subset of HTML. – MusiGenesis Aug 23 '18 at 12:23
  • @MusiGenesis you can use its unicode escape sequence : `\u00A0` – GrecKo Aug 23 '18 at 13:31
  • 1
    and I tried ` ` in a `Text` item with `both `StyledText` and `RichText` and it correctly displays a non breaking space – GrecKo Aug 23 '18 at 13:39
  • @GrecKo Ah, I see what I was doing wrong. Unfortunately, it seems that Qt renders both `\u00A0` and ` ` a *tiny* bit wider than a normal space with `textFormat: Text.RichText` and they both break the normal multiline word-wrapping. What I'm trying to do is have a `Label` that is positioned over a `TextArea` exactly mirror its text (even with multiple lines) even though I've embedded HTML tags into the label's text. This all works so long as the TextArea (which is set to textFormat: Text.PlainText) contains only single spaces. – MusiGenesis Aug 23 '18 at 15:38
  • @GrecKo With multiple consecutive spaces in the text of the text area, the label munges them into one space and thus the label no longer exactly mirrors the text in the textarea. I tried using both \u00A0 and   as replacements for the ordinary spaces in the original, but the very tiny difference in rendering width from a normal space also breaks the mirroring, and the lack of any word-wrapping also breaks it. – MusiGenesis Aug 23 '18 at 15:40
  • @GrecKo ` ` I have also tried, but the label treats these just like regular spaces (which they are) and merges them. – MusiGenesis Aug 23 '18 at 15:43
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/178626/discussion-between-grecko-and-musigenesis). – GrecKo Aug 23 '18 at 15:55

0 Answers0