Получить имя QML LineSeries при наведении указателя мыши на LineSeries - (LineSeries создается динамически) - PullRequest
0 голосов
/ 27 марта 2019

Я пытаюсь получить ссылку на динамически создаваемый LineSeries при наведении курсора.После создания LinesSeries я присоединяю обработчик сигнала к событию hovered.

Проблема заключается в следующем: из приведенного ниже упрощенного примера при наведении указателя мыши на LineSeries выводится имя последнего добавленного LineSeries.Когда следует напечатать название каждой серии добавленных LineSeries.Например, если 3 LineSeries были созданы с именами [«Строка A», «Строка B», «Строка C»], при наведении курсора на каждое из них следует печатать каждое соответствующее имя, но вместо этого печатать «Строка C» для всех 3LineSeries зависал обработчики событий.Что я делаю не так?

//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

Ответы [ 2 ]

1 голос
/ 28 марта 2019

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);

        }
    } 
1 голос
/ 28 марта 2019

Возможное решение - добавить аргументы, подобные functools.partial() в Python, и нам повезло, поскольку в есть эквивалентная реализация этого сообщения :

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