3

次のようなマップのズームを制御する qslider があります: connect(ui->zoomSlider, SIGNAL(valueChanged(int)), ui->map, SLOT(SetZoom(int))); ただし、このオンライン マップの応答は比較的遅いためです。

qslider の応答も非常に遅くなることがわかりました。つまり、スライダーをスライドさせても、マウスを離した位置に突然ジャンプするまで位置が変わりません。

どうすればこれを解決できますか?

4

1 に答える 1

0

あなたの処理を遅らせるための1つの可能な解決策signalは、Qt::QueuedConnection を使用してそれをスロットに接続することです。

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

Qt::QueuedConnection送信されvalueChangedたシグナルのイベントは、接続されたシグナルで発生するため、生成時に処理されませんdirectly。イベントはイベント ループ キューに追加されます。これがQt::QueuedConnectionQt 内での実装方法です。

Specially for Nejatこのアプローチをテストするには、次のコードを使用できます。

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

上記のコード スニペットを実行すると、ボタンを押すと次の出力が得られます。

signalReceived 
signalReceivedQueued 

キューに入れられたシグナルは最初に送信されますが、最後に受信されます。そして、これはあなたのケースで、送信されたシグナルの処理を優先するために使用できます。

ただし、ユーザーがスライダー イベントを頻繁に発行し、いずれにせよ UI がフリーズするため、キュー接続を使用しても役に立ちません。したがって、次のことを提案できます。

  1. UI がフリーズする正確な理由、コードのどの部分がフリーズするかを特定します。
  2. 非同期呼び出しまたはロジックを別のスレッドに移動するか、QtConcurrent
  3. Web ページでマップをスケーリングする方法を本当に制御できない場合は、QSlider によって生成されたすべてのイベントを無視し、500ミリ秒間隔で最後に生成されたイベントのみに反応するようにしてください。
于 2014-10-15T07:33:50.910 に答える