簡體   English   中英

Qt 集成C ++和Qml

[英]Qt. Integrating C++ and Qml

我對Qt相當陌生。 我大約兩個月前開始使用QWidgets應用程序,並且一切進展順利。 現在我有一個真正的問題。 我需要將我的c ++邏輯集成到我的Qml Ui中。 我將從我的QWidget adreesbook應用程序和用Qml編寫的UI中發布源代碼。 我需要做的是使我的應用程序與Qml集成的Ui一起使用。 它可以與QWidgets一起很好地工作,但是我不知道如何將其集成到Qml中。 我已經在網上搜索了2天,但是我似乎並不了解這些概念。 考慮到我對Qml完全不了解,任何建議都將不勝感激。

這是我的c ++ / QWidgets版本:

標頭:mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class MainWindow : public QMainWindow
    {
Q_OBJECT

public:
MainWindow(QMainWindow *parent = 0);
~MainWindow();
};

#endif // MAINWINDOW_H

地址簿

#ifndef ADDRESSBOOK_H
#define ADDRESSBOOK_H
#include <QMainWindow>
#include <QWidget>
#include <QTextEdit>
#include <QPushButton>
#include <QObject>
#include <QLineEdit>
#include <QLabel>
#include <QListWidget>
#include <QFrame>
#include <QList>
#include <QGridLayout>
#include <QString>
#include <QStringList>
#include <QKeyEvent>
#include <QCoreApplication>

class AddressBook4 : public QWidget
{
    Q_OBJECT

public:
    explicit AddressBook4(QWidget *parent = 0);
    ~AddressBook4();
    struct Details
    {
        QString name;
        QString street;
        QString number;
        QString notes;
    };

signals:

public slots:

private slots:
    void add(bool);
    void onListWidgetItemClicked(const QModelIndex &index);
    void importSql (bool);
    void exportSql (bool);

private:
    QTextEdit *m_pNotesTextEdit;
    QTextEdit *m_pDetailsTextEdit;

    QLineEdit *m_pNameLineEdit;
    QLineEdit *m_pStreetLineEdit;
    QLineEdit *m_pNumberLineEdit;

    QListWidget *m_pListWidget;

    QPushButton *m_pAddbutton;
    QPushButton *m_pImportbutton;
    QPushButton *m_pExportbutton;

    QFrame *m_pFrame;
    QLabel *m_pAddAdress;
    QLabel *m_pName;
    QLabel *m_pStreet;
    QLabel *m_pNumber;
    QLabel *m_pDetails;
    QLabel *m_pNotes;
    QLabel *m_pAddresses;

    QGridLayout *m_pGrid;
    QString *line;
    QListWidgetItem *item;

    QList<Details> m_detailsList;
};

#endif // ADDRESSBOOK_H

CPP文件:mainwindow.cpp

#include "mainwindow.h"
#include "addressbook.h"

MainWindow::MainWindow(QMainWindow *parent)
    : QMainWindow(parent)
{
    AddressBook4 *addressbook4 = new AddressBook4(this);
    setCentralWidget(addressbook4);
}

MainWindow::~MainWindow()
{
}

地址簿

#include "addressbook.h"
#include "mainwindow.h"
#include <QMainWindow>
#include <QWidget>
#include <QMessageBox>
#include <QTextEdit>
#include <QLabel>
#include <QLineEdit>
#include <QListWidget>
#include <QGridLayout>
#include <QFrame>
#include <QPushButton>
#include <QTextStream>
#include <QtCore>
#include <QString>
#include <QTextStream>
#include <QFile>
#include <QStringList>
#include <QtSql>
#include <QCoreApplication>
#include <QApplication>

#define FISIER_ADRESE "C:\\Users\\max\\Documents\\workspace\\AddressBook5\\Addresses.db"

AddressBook4::AddressBook4(QWidget *parent)
    : QWidget(parent)
{
    m_pGrid = new QGridLayout(this);

    m_pFrame = new QFrame(this);
    m_pGrid->addWidget(m_pFrame,1,0,8,4);
    m_pFrame->setFrameShape(QFrame::StyledPanel);

    m_pAddAdress = new QLabel("Add address", this);
    m_pGrid->addWidget(m_pAddAdress,1,2);
    m_pAddAdress->setAlignment(Qt::AlignRight | Qt::AlignVCenter);

    m_pName = new QLabel("Name:", this);
    m_pGrid->addWidget(m_pName,2,1);
    m_pName->setAlignment(Qt::AlignLeft | Qt::AlignTop);

    m_pNameLineEdit = new QLineEdit(this);
    m_pGrid->addWidget(m_pNameLineEdit,2,2);

    m_pStreet = new QLabel("Street:", this);
    m_pGrid->addWidget(m_pStreet,3,1);
    m_pStreet->setAlignment(Qt::AlignLeft | Qt::AlignTop);

    m_pStreetLineEdit = new QLineEdit(this);
    m_pGrid->addWidget(m_pStreetLineEdit,3,2);

    m_pNumber = new QLabel("Number:", this);
    m_pGrid->addWidget(m_pNumber,4,1);
    m_pNumber->setAlignment(Qt::AlignLeft | Qt::AlignTop);

    m_pNumberLineEdit = new QLineEdit(this);
    m_pGrid->addWidget(m_pNumberLineEdit,4,2);
    m_pNumberLineEdit->setFixedWidth(50);

    m_pNotes = new QLabel("Notes:", this);
    m_pGrid->addWidget(m_pNotes,6,1);
    m_pNotes->setAlignment(Qt::AlignLeft | Qt::AlignTop);

    m_pNotesTextEdit = new QTextEdit(this);
    m_pGrid->addWidget(m_pNotesTextEdit,6,2);

    m_pAddbutton= new QPushButton ("Add",this);
    m_pGrid->addWidget(m_pAddbutton, 7,2,Qt::AlignBaseline);

    m_pImportbutton= new QPushButton ("ImportSql",this);
    m_pGrid->addWidget(m_pImportbutton, 7,4,Qt::AlignBaseline | Qt::AlignLeft);
    m_pImportbutton->setFixedWidth(80);
    m_pImportbutton->setShortcut(QKeySequence(Qt::Key_Insert));

    m_pExportbutton= new QPushButton ("ExportSql",this);
    m_pGrid->addWidget(m_pExportbutton, 7,4,Qt::AlignBaseline | Qt::AlignRight);
    m_pExportbutton->setFixedWidth(80);

    m_pAddresses = new QLabel("Addresses", this);
    m_pGrid->addWidget(m_pAddresses,1,4);
    m_pAddresses->setAlignment(Qt::AlignRight | Qt::AlignVCenter);

    m_pListWidget = new QListWidget(this);
    m_pGrid->addWidget(m_pListWidget,2,4,3,1);

    m_pDetails = new QLabel("Details", this);
    m_pGrid->addWidget(m_pDetails,5,4);
    m_pDetails->setAlignment(Qt::AlignRight | Qt::AlignVCenter);

    m_pDetailsTextEdit = new QTextEdit(this);
    m_pGrid->addWidget(m_pDetailsTextEdit,6,4);
    m_pDetailsTextEdit->setReadOnly(true);

    setLayout(m_pGrid);

    connect(m_pAddbutton, SIGNAL(clicked(bool)),
            this, SLOT(add(bool)));
    connect(m_pListWidget, SIGNAL(clicked(QModelIndex)),
            this, SLOT(onListWidgetItemClicked(const QModelIndex)));
    connect(m_pImportbutton, SIGNAL(clicked(bool)),
            this, SLOT(importSql(bool)));
    connect(m_pExportbutton, SIGNAL(clicked(bool)),
            this, SLOT(exportSql(bool)));

}

//Reads the user imput data from m_pNameLineEdit, m_pStreetLineEdit, m_pNumberLineEdit,
//m_pNotesiTextEdit and creates a new QListWidget item every time when clicked.
void AddressBook4::add(bool)
{
    if ((m_pNameLineEdit->text().isEmpty()) || (m_pStreetLineEdit->text().isEmpty())
       || (m_pNumberLineEdit->text().isEmpty()) || (m_pNotesTextEdit->toPlainText().isEmpty()))
    {
         QMessageBox::warning(this, "Warning", "You need to complete all the fields");
    } else {
         int index = m_pListWidget->count();
         m_pListWidget->addItem("address " + QString::number(index));

         Details detail;
         detail.name = m_pNameLineEdit->text();
         detail.street = m_pStreetLineEdit->text();
         detail.number = m_pNumberLineEdit->text();
         detail.notes = m_pNotesTextEdit->toPlainText();

         m_detailsList.append(detail);
    }
}

//Prints the data from every QListWidgetItem in the m_pDetailsTextEdit when clicked
void AddressBook4::onListWidgetItemClicked(const QModelIndex &index)
{
    m_pDetailsTextEdit->clear();
    m_pDetailsTextEdit->append("Name: " + m_detailsList.at(index.row()).name);
    m_pDetailsTextEdit->append("Street: " + m_detailsList.at(index.row()).street);
    m_pDetailsTextEdit->append("Nr.: " + m_detailsList.at(index.row()).number);
    m_pDetailsTextEdit->append("Notes: " + m_detailsList.at(index.row()).notes);
}

//Imports data from the Sql database and attributes it to QListWidget items
void AddressBook4::importSql(bool)
{
    QSqlDatabase my_db = QSqlDatabase::addDatabase("QSQLITE");
    my_db.setDatabaseName(FISIER_ADRESE);
    my_db.open();

    qDebug() << "Connected to database..." ;

    QSqlQuery my_qry("SELECT * FROM Addresses");
    int idx_Name = my_qry.record().indexOf("Name");
    int idx_Street = my_qry.record().indexOf("Street");
    int idx_Number = my_qry.record().indexOf("Number");
    int idx_Notes = my_qry.record().indexOf("Notes");
    while (my_qry.next()) {
        Details detail;
        detail.name = my_qry.value(idx_Name).toString();
        //qDebug() << detail.name;
        detail.street = my_qry.value(idx_Street).toString();
        //qDebug() << detail.street;
        detail.number = my_qry.value(idx_Number).toString();
        //qDebug() << detail.number;
        detail.notes = my_qry.value(idx_Notes).toString();
        //qDebug() << detail.notes <<"\n";
        m_detailsList.append(detail);
        int index = m_pListWidget->count();
        m_pListWidget->addItem("address " + QString::number(index));
    }
}

//Reads through every QlistWidget item and inserts the containing data into the Sql database
void AddressBook4::exportSql(bool)
{
    QSqlDatabase my_db = QSqlDatabase::addDatabase("QSQLITE");
    my_db.setDatabaseName(FISIER_ADRESE);

    if (!my_db.open()) {
        QMessageBox::warning(this, "Warning", "Cannot connect to the database");
    } else {
        qDebug() << "Connected to database...";
        QSqlQuery my_qry;
        my_qry.prepare( "CREATE TABLE IF NOT EXISTS Addresses (Name QSTRING, "
                        "Street QSTRING, Number QSTRING, Notes QSTRING)" );
          if( !my_qry.exec() )
            qDebug() << my_qry.lastError();
          else
            qDebug() << "Table created!";

          for (int row = 0; row < m_pListWidget->count(); ++row) {
              item = m_pListWidget->item(row);
              Details detail = m_detailsList.at(row);

          my_qry.prepare( "INSERT INTO Addresses ( Name, Street, Number, Notes) "
                          "VALUES (:Name, :Street, :Number, :Notes)");
          my_qry.bindValue(":Name", detail.name);
          my_qry.bindValue(":Street", detail.street);
          my_qry.bindValue(":Number", detail.number);
          my_qry.bindValue(":Notes", detail.notes);
            if( !my_qry.exec() )
              qDebug() << my_qry.lastError();
            else
              qDebug() << "Inserted!";
        }
    }

}

AddressBook4::~AddressBook4()
{
}

main.cpp

#include <QApplication>
#include "addressbook.h"
#include "mainwindow.h"
#include <QMainWindow>
#include <QWidget>
#include <QTextStream>
#include <QString>
#include <QTextStream>
#include <QFile>
#include <QStringList>
#include <QtCore>
#define STYLE_SHEET "C:\\Users\\max\\Documents\\workspace\\AddressBook4\\stylesheet.css"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    MainWindow w;
    w.setWindowTitle("AddressBook4");
    w.show();

    //QFile file (STYLE_SHEET);
    //if (file.open(QFile::ReadOnly | QFile::Text)) {
       // QTextStream in(&file);
        //QString styleStr = in.readAll();
        //qDebug() << styleStr;
        //file.close();
        //a.setStyleSheet(styleStr);
    //}

    return a.exec();
}

現在,我將發布我的QtQuick版本。

標頭:buttons.h

#ifndef BUTTONS_H
#define BUTTONS_H

#include <QObject>
#include <QDebug>

class Buttons : public QObject
{
    Q_OBJECT
public:
    explicit Buttons(QObject *parent = 0);

public slots:
    void addClicked(const QStringList &in);
    void exportClicked();
    void importClicked();
};

#endif // BUTTONS_H

Cpp文件:main.cpp

#include <QApplication>
#include <QQmlApplicationEngine>
#include "buttons.h"
#include <QQmlContext>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    Buttons buttons;

    engine.rootContext()->setContextProperty("buttons", &buttons);

    return app.exec();
}

button.cpp

#include "buttons.h"
#include <QApplication>
#include <QObject>
#include <QString>
#include <QDebug>

Buttons::Buttons(QObject *parent) :
    QObject(parent)
{
}
void Buttons::addClicked(const QStringList &in)
{
    qDebug() << in;
}

void Buttons::exportClicked()
{
    qDebug() << "Works";
}

void Buttons::importClicked()
{
    qDebug() << "Works";
}

還有我的main.qml文件

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.3

ApplicationWindow {
    visible: true
    title: "AddressBookQml"
    property int margin: 11


    GridLayout {
        id: mainLayout
        anchors.fill: parent
        anchors.margins: margin


        GroupBox {
            id: gridBox
            title: "Add address"
            Layout.fillWidth: true
            Layout.fillHeight: true

            GridLayout {
                id: gridLayout
                rows: 5
                columns: 2
                flow: GridLayout.TopToBottom
                anchors.fill: parent

                Label { text: "Name" }
                Label { text: "Street" }
                Label { text: "Number" }
                Label { text: "Notes"}
                Button {
                    text: "Add "
                    onClicked: buttons.addClicked("Name:" + textfield_1.text + "Street:" +
                                                      textfield_2.text + "Number:" +
                                                      textfield_3.text + "Notes:" + textArea_1.text)

                }

                TextField {
                    id: textfield_1
                    Layout.fillWidth: true
                }
                TextField {
                    id: textfield_2
                    Layout.fillWidth: true
                }
                TextField {
                    id: textfield_3
                }
                TextArea {
                    id: textArea_1
                    Layout.rowSpan: 1
                    Layout.fillHeight: true
                    Layout.fillWidth: true
                }

            }
        }

        GroupBox {
            id: gridBox2
            Layout.fillWidth: true
            Layout.fillHeight: true

            GridLayout {
                id: gridLayout2
                rows: 5
                flow: GridLayout.TopToBottom
                anchors.fill: parent

                GridLayout {
                    id: gridLayout4
                    rows: 2

                    flow: GridLayout.TopToBottom
                    anchors.fill: parent

                    Label { text: "Addresses" }

                    ListModel {
                        id: model
                        ListElement {
                            name: 'Address 1'

                        }
                        ListElement {
                            name: 'Address 2'
                        }

                    }

                    ScrollView {
                        ListView {
                            id: list
                            anchors.fill: parent
                            model: model


                            Layout.rowSpan: 1
                            Layout.fillHeight: true
                            Layout.fillWidth: true

                            delegate: Component {
                                Item {
                                    width: parent.width
                                    height: 15
                                    Column {
                                        Text { text: name }
                                        //Text { text: 'Number:' + number }
                                    }
                                    MouseArea {
                                        anchors.fill: parent
                                        onClicked: list.currentIndex = index
                                    }
                                }
                            }
                            highlight: Rectangle {
                                color: "white"
                                Text {
                                    anchors.centerIn: parent
                                }
                            }
                            focus: true
                            onCurrentItemChanged: console.log(model.get(list.currentIndex).name + ' selected')
                        }
                    }
                }

                Label { text: "Detalii" }

                TextArea {
                    Layout.rowSpan: 2
                    Layout.fillHeight: true
                    Layout.fillWidth: true
                    readOnly: true
                }

                GroupBox {
                    id: gridBox3
                    Layout.fillWidth:  true

                    GridLayout {
                        id: gridLayout3
                        rows: 1
                        flow: GridLayout.LeftToRight
                        Button {
                            text: "ExportSql "
                            onClicked: buttons.exportClicked()
                        }
                        Button {
                            text: "ImportSql "
                            onClicked: buttons.importClicked()
                        }
                    }
                }
            }
        }
    }
}

在C ++中,您可以定義可在QML中使用的屬性

class MyQuickView : public QQuickView {
  MyQuickView (){
    rootContext()->setContextProperty('mySelf',     this);
    rootContext()->setContextProperty('myProperty', 5);
    setSource(QUrl.fromLocalFile(myQmlFile.qml));
    mySignal.connect
  }

  public slots:
    void mySlot(int i);
};

在QML中,您可以調用廣告位並讀取屬性

Item {
  Button {
    onClicked: mySelf.mySlot(mySelf.myProperty);
  }
}

在這里,您可以找到如何將C ++信號連接到QML插槽:

https://stackoverflow.com/a/8840945/264359

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM