Qt. Integrating C++ and Qml
Qt. Integrating C++ and Qml
我对Qt相当陌生。大约两个月前,我开始使用QWidgets应用程序,事情进展顺利。现在我有一个真正的问题。我需要将我的 c++ 逻辑集成到我的 Qml UI 中。我将发布我的QWidget adreesbook应用程序和用Qml编写的UI的源代码。我需要做的是让我的应用程序与 Qml 集成的 UI 一起工作。它与QWidgets一起工作,但我不知道如何将它集成到Qml中。我已经在网上搜索了 2 天,但我似乎没有掌握这些概念。鉴于我对 Qml 完全是菜鸟,任何建议都将不胜感激。
这是我的c ++/QWidgets版本:
头:主窗口.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QMainWindow *parent = 0);
~MainWindow();
};
#endif // MAINWINDOW_H
地址簿.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 文件:主窗口.cpp
#include "mainwindow.h"
#include "addressbook.h"
MainWindow::MainWindow(QMainWindow *parent)
: QMainWindow(parent)
{
AddressBook4 *addressbook4 = new AddressBook4(this);
setCentralWidget(addressbook4);
}
MainWindow::~MainWindow()
{
}
地址簿.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()
{
}
主.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版本。
头:按钮.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 文件:主.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();
}
按钮.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";
}
和我的主.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
相关文章:
- 从C++实例化QML
- 使用CMake创建QML插件
- QT通过C++添加映射QML项目
- 如何在没有信号的情况下从C++执行QML插槽
- QML按钮点击功能执行顺序
- C++核心准则 C35 对于接口类"A base class destructor should be either public and virtual, or protected and nonv
- QML:修改在不同QML文件(而非main.QML)中定义的子对象的属性
- 建议在运行时将带有类实例的列表从c++导入qml
- 为什么C++逐位AND运算符在不同大小的操作数中表现为这样
- 为什么 Clang 不允许"and"作为函数名称?
- Qt Quick-如何仅从c++代码与qml属性交互
- QAbstractTableModel::header data and QML TableView
- Qt/QML: WebEngineView and ScrollView
- Integrating c++ and qml
- QML and QQuickImageProvider size
- Qt, c++ QML and HWND
- Integrate C++ and QML. Qt 5.4
- Connecting QML and Qt
- QOpenglWidget and QML Quick
- Qt. Integrating C++ and Qml