如何从 C++ 访问特定 QML 控件的事件
how to access events of a specific QML control from c++
有没有办法从 c++ 访问 QML 控件(如按钮)的信号(如clicked()
)。假设我有该特定控件的内存地址。我只想模拟来自 c++ 代码的单击事件。
容易。 您只需在具有 QObject 基础的 C++ 对象中创建一个插槽,确保将其注册为 QML 类型,然后在 QML 文档中"实例化"它,并使用 connect() 通过 QML 将所需的信号连接到C++对象,并从C++端处理逻辑。
例:
我有一个矩形,我想从中获取 onWidthChanged 信号,并在我的类 ShapeTracker 中使用它,它可以跟踪形状何时更改或其他任何内容
在主.cpp:
#include "shapetracker.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
/* this is where you register ShapeTracker as a QML type that can be
accessed through the QML engine even though its a C++ QObject */
qmlRegisterType<ShapeTracker>("my_cpp_classes", 1, 0, "ShapeTracker");
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
然后在
主.qml
import QtQuick 2.6
/* import the C++ class you registered into this QML document */
import my_cpp_classes 1.0
Window {
visible: true
Item {
/* set up a parent item that has a signal which is exposed to
the ShapeTracker object and the Rectangle you want to track */
id: myRootItem
signal rectangleChanged(var newWidth)
/* Heres our special Rectangle from QML that will send a signal when
its width changes */
Rectangle {
id: specialRectangle
width: 250
/* send the signal rectangleChanged(width) from our parent item
root item whenever width changes
*/
onWidthChanged: function() { rectangleChanged(width); }
}
/* Special Button that when clicked enlarges the Rectangle but
10px */
Button {
id: mySpecialButton
onClicked: { click_handler(mouse); }
function click_handler(mouse): {
if (specialRectangle.width < 500)
specialRectangle.width += 10;
}
}
/* Heres the actual ShapeTracker instance, which exists
as a QObject inside of the QML context, but has its methods
which are declared in C++, and exposed to the QML engine */
ShapeTracker {
id: myShapeTracker
/* similar to a constructor, but more like a callback */
Component.onCompleted: {
/* connect our signal from the parent root Item called
"rectangleChanged" to the ShapeTracker's Slot called
"myRectangleChangeHandler" */
myRootItem.rectangleChanged.connect(myShapeTracker.myRectangleChangeHandler);
/* connect send_mouse_click to the click_handler of
the button */
myShapeTracker.send_mouse_click.connect(mySpecialButton.click_handler)
}
}
}
}
在shapetracker.h中,您只需添加一个名为myRectangleChangeHandler的新插槽,每当通过QML发送信号以通过C++进行处理时,它都会接收该信号
class ShapeTracker : public QObject {
Q_OBJECT
public:
ShapeTracker(QObject *parent = 0 );
signal:
void send_mouse_click(QMouseEvent *event);
public slots:
void myRectangleChangeHandler(QVariant newWidth) {
/* Perform a mouse click on our QML Object mySpecialButton
using QQuickItem::mousePressEvent and sending it via
signal back to QML */
QMouseEvent myEvent(QEvent::MouseButtonPress, QPointF(1,1), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QMouseEvent* pressEvent = QQuickItem::mousePressEvent(&myEvent);
emit send_mouse_click(pressEvent);
}
};
在摘要中,
您将C++ QObject 公开给 QML,然后使用 object.signal.connect(cppObject.desired_slot)
为了连接它们 - 所有额外的东西都是为了一个功能示例,以防以后有人需要它
实际上,您甚至不需要此功能,因为onClick事件中发生的任何事情都可以很容易地放入任何其他属性中,例如
Rectangle {
id: rect
signal customClick(var var1)
onCustomClick : { console.log(var1); }
}
Item {
rect.customClick(1);
}
简单的方法是手动调用所有接收插槽。但那将是乏味且容易出错的。
您可以尝试实现 QObject 的子类,该子类具有一个发出信号clicked()
的插槽onClicked()
并将其用作按钮和按钮控制的元素之间的填充程序。将按钮clicked()
连接到新对象onClicked()
,然后将新对象连接到原始接收器。然后调用onClicked()
将触发该行为。
这是一个非常简单的示例,我还没有通过编译器运行它。
ButtonShim.hpp
#include <QObject>
class ButtonShim : public QObject {
Q_OBJECT
public:
ButtonShim(QObject *parent = 0);
virtual ~ButtonShim();
public slots:
void onClicked();
signals:
void clicked();
};
纽扣希姆.cpp
#include "ButtonShim.hpp"
ButtonShim::ButtonShim(QObject *parent) : QObject(parent) {
}
ButtonShim::~ButtonShim() {
}
void ButtonShim::onClicked() {
// All we do here is emit the clicked signal.
emit clicked();
}
一些文件.cpp
#include <bb/cascades/Button>
#include "ButtonShim.hpp"
...
ButtonShim * pButtonShim = new ButtonShim(pButton); // pButtonShim will live as long as pButton
bool c = connect(pButton, SIGNAL(clicked()), pButtonShim, SLOT(onClicked()));
c = connect(pButtonShim, SIGNAL(clicked()), pSomeObject, SLOT(onButtonClicked()));
...
// to simulate a click of pButton
pButtonShim->onClicked();
一些文件.qml
// assuming ButtonShim has been exposed to QML from your application
...
attachedObjects: [
ButtonShim {
id: buttonShim
onClicked: {
clickedLabel.text = "I've been clicked";
}
}
]
...
Label {
id: clickedLabel
text: "I haven't been clicked"
}
Button {
text: "Click Me"
onClicked: {
buttonShim.onClicked();
}
}
您可以查看测试代码。在那里,他们从加载到引擎中的QML文件中获取对象。
如果你有一个QObject,你可以只打电话给信号,因为,AFAIR
public signals:
void clicked();
由 MOC 扩展为
public:
void clicked();
- 在createdialog创建的窗口中捕获用于编辑控件的OnMouseMove消息
- WinAPI 在单击第一个对话框上的按钮控件并销毁第一个对话框后创建第二个对话框
- 在编译时,C++项目抛出错误 C2228,这是预期的,因为控件在运行时未达到该点
- 如何更改窗体上所有控件的标题?[C++生成器]
- 双击更改 mfc 中列表控件中的行的颜色
- 派生的 wxPanel 控件如何访问其中包含 wxDialog 中的数据?
- 如何从代码本身向 wxwidgets 中的文本控件插入字符?
- 如何在MFC中的静态文本控件上插入图标?
- 我的主窗口在创建时或单击更新区域时是否会收到编辑控件?
- 如何在Qt C++中向自定义控件添加属性?
- C/C++ 检测双击 TVItem 的常用控件
- 从C++标头中导入常量而不是硬编码它们:扩展 .net 控件?
- 控件不会在选择函数旁边移动
- MFC:我们能否扩展CEditView中存在的CEdit控件类行为
- 通过嵌入式 IWebBrowser2 控件中的链接打开 youtube 搜索失败
- 查找素数:错误:控件到达非void函数的末尾
- C++ 获取"控件可能会到达约翰逊-特罗特代码上的非空函数的末尾
- 在Qt Qml控件中,ApplicationWindow在运行时缺少本机外观的主题
- 如何从 C++ 访问特定 QML 控件的事件
- 如何在QML中更新基于加载器的底部控件