Qt的。集成C ++和Qml

时间:2016-07-08 14:51:51

标签: c++ qt qml

我是Qt的新手。我在两个月前开始使用QWidgets应用程序,事情进展顺利。现在我有一个真正的问题。我需要将我的c ++逻辑集成到我的Qml Ui中。我将从我的QWidget adreesbook应用程序和用Qml编写的UI发布我的源代码。我需要做的是让我的应用程序使用Qml集成的Ui。它适用于QWidgets,但我不知道如何将它集成到Qml中。我一直在网上搜索2天,但我似乎没有掌握这些概念。鉴于我是关于Qml的完全noob的事实,任何建议将不胜感激。

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

接头: mainwindow.h

List<int> missing = lstBaskets
    .SelectMany(s => s.Fruit)
    .Select(s => s)
    .Except(lstFruits.Select(s => s.Id))
    .ToList();

addressbook.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class MainWindow : public QMainWindow
    {
Q_OBJECT

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

#endif // MAINWINDOW_H

CPP文件: mainwindow.cpp

#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

addressbook.cpp

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

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

MainWindow::~MainWindow()
{
}

的main.cpp

#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()
{
}

现在我将发布我的QtQuick版本。

接头: buttons.h

#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();
}

Cpp文件: main.cpp中

#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

buttons.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();
}

我的main.qml文件

#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";
}

1 个答案:

答案 0 :(得分:1)

在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