3
votes

I have a qslider to control the zooming of a map like this: connect(ui->zoomSlider, SIGNAL(valueChanged(int)), ui->map, SLOT(SetZoom(int))); However, because this online-map response relatively slow.

I found that the qslider's response also becomes very slow which means when you slide the slider, it's position won't change until suddenly it jump to the position where you release your mouse.

How could I solve this?

1
I've seen things like this happen before because the updating of the widget it's controlling causes the whole ui to wait for it to finish. You need to. Are it so the updating widget doesn't cause everything else to stall. - will
you can try to call connect with Qt::QueuedConnection argument. i'm not 100% sure, but if this will put new event to the loop and continue thread execution, then your problem will be solved - Max Go
connect(ui->zoomSlider, SIGNAL(valueChanged(int)), ui->map, SLOT(SetZoom(int)), Qt::QueuedConnection); - Max Go
@N1ghtLight The two objects are in the same thread (main thread). So using Qt::QueuedConnection is useless. - Nejat
@Nejat, I described what I meant in my answer. And it works differently even in the same thread. - Max Go

1 Answers

0
votes

One possible solution to delay processing of your signal is to connect it with slot by using Qt::QueuedConnection.

connect(ui->zoomSlider, SIGNAL(valueChanged(int)), ui->map, SLOT(SetZoom(int)), Qt::QueuedConnection);

With Qt::QueuedConnection emitted valueChanged signal event will be not processed at the time of generation, as it happens with directly connected signals. Event will be added to the event loop queue. This is how Qt::QueuedConnection is implemented inside Qt.

Specially for Nejat to test this approach it's possible to use following code:

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void signalReceived();
    void signalReceivedQueued();

    void buttonPressed();

signals:

    void directConnectedSignal();
    void queuedConnectedSignal();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    connect(this, SIGNAL(directConnectedSignal()), SLOT(signalReceived()), Qt::DirectConnection);
    connect(this, SIGNAL(queuedConnectedSignal()), SLOT(signalReceivedQueued()), Qt::QueuedConnection);

    connect(ui->pushButton, SIGNAL(pressed()), SLOT(buttonPressed()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::signalReceived()
{
    qDebug() << "signalReceived";
}

void MainWindow::signalReceivedQueued()
{
    qDebug() << "signalReceivedQueued";
}

void MainWindow::buttonPressed()
{
    emit queuedConnectedSignal();
    emit directConnectedSignal();
}

If you run code snippet above you will get following output on button press:

signalReceived 
signalReceivedQueued 

Queued signal is emitted first, but received last. And this can be used in your case to prioritize processing of emitted signals.

However most of all using of queued connection will not help you, because user emits slider event too frequently and UI will freeze in any case. So, I can suggest following:

  1. Determine why exactly UI is freezes, what part of code freezing it.
  2. Try to avoid freezing by asynchronous calls or by moving logic into separate thread, or by using QtConcurrent
  3. If you really can't control the way how map is scaled in your webpage, try to ignore all events generated by the QSlider and react only on last generated in 500 ms interval, for example.