在写qml项目时发现的问题:qml的信号能传给qwidget,但是qwidget的信号传不到qml里面来,话不多说,直接上代码:
qwidget窗口类头文件:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <qquickview.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
public slots:
void receiveFromQml();
private slots:
void on_pushButton_clicked();
};
#endif // MAINWINDOW_H
qwidget窗口类源文件:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->quickWidget1->setSource(QUrl::fromLocalFile("left.qml"));
QObject*pRoot=(QObject*)this->ui->quickWidget1->rootObject();
if(pRoot!=NULL)
{
connect(pRoot,SIGNAL(qmlSignal()),this,SLOT(receiveFromQml()));
//connect(ui->pushButton,SIGNAL(clicked),pRoot,SLOT(cSignal));//这种写法会导致信号槽连接不上
connect(ui->pushButton, &QPushButton::clicked, this, [=]()
{
QMetaObject::invokeMethod(pRoot, "cSignal");
});
}
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::receiveFromQml()
{
this->ui->pushButton->setText("qml给qwidget信号");
}
void MainWindow::on_pushButton_clicked()
{
qDebug()<<"防gank";
}
其中
connect(ui->pushButton,SIGNAL(clicked),pRoot,SLOT(cSignal));这种写法会导致信号槽连不上,需要采用另一种写法,调用QMetaObject::invokeMethod这个函数才能成功绑定。这个函数允许你通过元对象系统动态地调用一个对象的方法。
bool QMetaObject::invokeMethod(void *object, const char *method, const char *type, void **argv, int argc, Qt::ConnectionType connectionType = Qt::AutoConnection) const;
- 指定要调用的对象(
object
)。 - 指定要调用的方法名(
method
)。 - 指定方法参数的类型(
type
)。 - 指定方法参数(
argv
)。 - 指定方法参数的数量(
argc
)。 - 指定连接类型(
connectionType
),默认为Qt::AutoConnection
。
具体的可以直接看文档, 当你需要在不直接访问对象的情况下调用其方法时,可以使用 invokeMethod()
。例如,如果你有一个对象模型,并且想要从另一个对象动态地触发某个操作,你可以使用 invokeMethod()
来调用相应的操作方法。
qml代码:
import QtQuick 2.1
Rectangle {
id:root
color: "green"
width: 200
height: 200
//发送给qwidget的信号
signal qmlSignal
//从QTwidget接收的信号
signal cSignal
Text {
id: mytext
text: qsTr("click")
font.pixelSize: 24
anchors.centerIn: parent.Center
}
MouseArea{
anchors.fill: parent
onClicked: qmlSignal()
}
onCSignal: {
root.color="blue"
mytext.text="call the qml"
}
}