Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

[SOLVED] How can I wrap QPushButton into QDeclarativeItem?



  • Hello,

    I need to bind QPushButton in order to use it, inside QML.
    I have writen the above code,

    @
    class Button : public QDeclarativeItem
    {
    Q_OBJECT

    Q_PROPERTY(QString text READ text WRITE setText)
    Q_PROPERTY(bool enabled READ enabled WRITE setEnabled)
    Q_PROPERTY(bool flat READ flat WRITE setFlat)
    Q_PROPERTY(QString iconSource READ iconSource WRITE setIconSource)

    public:

    Button(QDeclarativeItem *parent = 0);
    ~Button();
    
    QString text() const;
    void setText(const QString& text);
    
    bool enabled() const;
    void setEnabled(const bool enable);
    
    QString iconSource() const;
    void setIconSource(const QString& iconSource);
    
    bool flat() const;
    void setFlat(const bool flat);
    

    signals:
    void clicked();

    private:
    QPushButton *m_nativeWidget;
    QGraphicsProxyWidget *m_proxyWidget;
    bool m_enabled;
    bool m_flat;
    QString m_text;
    QString m_iconSource;
    };

    Button::Button(QDeclarativeItem *parent)
    : QDeclarativeItem(parent)
    {
    setFlag(QGraphicsItem::ItemHasNoContents, false);
    m_nativeWidget = new QPushButton();
    m_proxyWidget = new QGraphicsProxyWidget(this);
    m_proxyWidget->setWidget(m_nativeWidget);
    connect(m_nativeWidget, SIGNAL(clicked()), this, SIGNAL(clicked()));
    }

    Button::~Button()
    {
    delete m_nativeWidget;
    }

    bool Button::enabled() const
    {
    return m_enabled;
    }

    bool Button::flat() const
    {
    return m_flat;
    }

    QString Button::iconSource() const
    {
    return m_iconSource;
    }

    QString Button::text() const
    {
    return m_text;
    }

    void Button::setEnabled(const bool enable)
    {
    m_enabled = enable;
    m_nativeWidget->setEnabled(enable);
    }

    void Button::setFlat(const bool flat)
    {
    m_flat = flat;
    m_nativeWidget->setFlat(flat);
    }

    void Button::setIconSource(const QString& iconSource)
    {
    m_iconSource = iconSource;
    m_nativeWidget->setIcon(KIcon(iconSource));
    }

    void Button::setText(const QString& text)
    {
    m_text = text;
    m_nativeWidget->setText(text);
    }
    @

    I have two issues with the above code,

    1. inside a column I can't paint more that 1 Button. Only 1 is visible.
    2. my Button Component is ugly. It doesn;t render property but I can click it.

    thanks in advance



  • QGraphicsProxyWidget is your friend here.



  • I ported my code into QGraphicsProxyWidget, this time 3 buttons appear but still there aren't the
    normal QPushButtons,(still they are ugly). What am I missing? QWidget::setAttribute?

    Also in QML I use them like this,

    @
    Column {
    spacing: 5
    height: parent.height
    anchors {
    right: backGround.right
    top: parent.top
    topMargin: parent.height/6
    rightMargin: parent.height/4
    }

            Button {
                id: aboutButton
                text: "  About"
                iconSource: "something"
                flat: false
                enabled: true
                onClicked: {
                    pageStack.push(Qt.createComponent("AboutPage.qml"))
                    console.log("go to the aboutPage, this is AboutPage.qml")
                }
             /*   states: [
                    State {
                        name: "disable"
                        PropertyChanges {
                            target: aboutButton
                            enabled: false
                        }
                    }
                ]*/
            }
    
            Button {
                id: configureButton
                iconSource: "configure"
                flat: true
                enabled: true
                onClicked: {
                    configItem.openDialog()
                    console.log("open the config dialog")
                }
          /*      states: [
                    State {
                        name: "disable"
                        PropertyChanges {
                            target: configureButton
                            enabled: false
                        }
                    }
                ]*/
            }
    
            Button {
                id: videoButton
                iconSource: "youtube"
                flat: true
                enabled: true
                onClicked: {
                    videoHandler.openUrl(effectVideoSource)
                }
    

    @

    I understand that I can't use states so what should I do?
    I tried to wrap the c++ binding inside an Item Component, like

    @
    import QtQuick 1.1
    Item {
    property string text
    property string iconSource
    property bool flat
    property bool enabled
    signal clicked
    Button {
    id: button
    text: text
    iconSource: iconSource
    flat: flat
    enabled: enabled
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
             button.clicked
        }
    }
    

    }
    @

    but when I did the buttons weren't there.(I didn't see any buttons).

    In both case my 3 buttons are a part of a delegate, so when I scroll my application disappears..
    Do you know why?



  • Is this just an "exercise" or a real case scenario? Why not "create" a button component using only qml?



  • This is a real case scenario.

    I can create a component but I want it to be like the Qwidgets(the look and feel), also I don't have images with Qt style available



  • I solved the issue.

    In my code I do,

    @
    delete m_nativeWidget;
    @

    this cause the crash. setWidget took the ownership of my widget


Log in to reply