悬停时,我试图获取对动态创建的LineSeries的引用。创建LinesSeries之后,我将信号处理程序附加到悬停的事件上。
问题是: 从下面的简化示例中,当我将鼠标悬停在LineSeries上时,它会打印出最后添加的LineSeries的名称。什么时候应该打印添加的每个LineSeries的系列名称。 例如,如果创建的3个LineSeries的名称为[“ Line A”,“ Line B”,“ Line C”],则将鼠标悬停在每个名称上时,应打印每个对应的名称,而对所有3个名称都打印“ Line C” LineSeries悬停的事件处理程序。我在做什么 错误吗?
//dataset is a dictionary(QVariant) of items where each item is the name of the line series
for(var name in dataset) {
var series = chart.createSeries(ChartView.SeriesTypeLine, name, xAxis, yAxis);
series.name = name;
series.hovered.connect(
function (point,state){
if (state){
console.log(">>>"+ name); // <- should print the name of each series
}
});
我觉得这与将name变量的当前值绑定到onhovered事件处理程序有关,但是我不确定如何执行此操作。我知道在常规JS中它们会做类似的事情
functionName.bind({... code ...},this);
感谢您的帮助。
-E
答案 0 :(得分:1)
一种可行的解决方案是在Python中添加类似于functools.partial()
的参数,由于this post中有等效的实现,因此我们很幸运:
// https://stackoverflow.com/a/33261231/6622587
function partial() {
var args = Array.prototype.slice.call(arguments);
var fn = args.shift();
return function() {
var nextArgs = Array.prototype.slice.call(arguments);
// replace null values with new arguments
args.forEach(function(val, i) {
if (val === null && nextArgs.length) {
args[i] = nextArgs.shift();
}
});
// if we have more supplied arguments than null values
// then append to argument list
if (nextArgs.length) {
nextArgs.forEach(function(val) {
args.push(val);
});
}
return fn.apply(fn, args);
}
}
// ...
for(var name in dataset) {
var series = chart.createSeries(ChartView.SeriesTypeLine, name, xAxis, yAxis);
var fun = function(name, point, state){
if (state){
console.log(">>>"+ name);
}
};
series.hovered.connect(partial(fun, name));
}
答案 1 :(得分:1)
name
包含迭代完成时数组的最后一个值,因此连接处理程序将始终采用该值。为了避免这种现象,您应该使用闭包,如下所示:
Component.onCompleted: {
var dataset = ["aaa","bbb","ccc"];
for(var name in dataset) {
var series = chart.createSeries(ChartView.SeriesTypeLine, dataset[name], xAxis, yAxis);
(function(series){
series.name = dataset[name];
series.hovered.connect(function (point, state)
{
if (state)
{
console.log(series.name);
}
});
})(series);
}
}