QwtPlotMarker 和 QwtPlotPicker 是 Qwt 庫中用于增強 QwtPlot 功能的兩個重要類。它們分別用于在圖中添加標記和實現交互式的選擇或拖動功能。
QwtPlotPicker 提供了交互式的選擇工具,它允許用戶通過鼠標點擊或拖動來選擇圖表中的數據點或區域。這對于實現縮放、平移或者其他基于用戶輸入的操作非常有用。
主要功能
? 選擇模式:可以選擇不同的選擇模式,如點選擇、矩形選擇、多邊形選擇等。
? 事件處理:通過信號和槽機制響應用戶的交互行為(如鼠標點擊、拖動等)。
? 坐標轉換:提供從屏幕坐標到數據坐標的轉換方法。
? 自定義繪圖:可以通過重寫繪制函數來自定義選擇框或其他視覺反饋。
示例代碼 1
#include <QApplication>
#include <QwtPlot>
#include <QwtPlotCurve>
#include <QwtPlotPicker>
#include <QwtPickerMachine>
#include <QwtPlotPanner> // 如果需要平移功能class PickerTracker : public QObject {Q_OBJECTpublic slots:void trackerText(const QString &text) {qDebug() << "Tracker Text:" << text;}void selected(const QPointF &pos) {qDebug() << "Selected Position:" << pos;}
};int main(int argc, char *argv[]) {QApplication app(argc, argv);// 創建并配置 QwtPlotQwtPlot plot;plot.setTitle("QwtPlotPicker Example");// 添加一條曲線QwtPlotCurve *curve = new QwtPlotCurve("Sample Curve");QVector<double> xData = {0.0, 1.0, 2.0, 3.0, 4.0};QVector<double> yData = {0.0, 1.0, 4.0, 9.0, 16.0};curve->setSamples(xData, yData);curve->attach(&plot);// 創建并配置 QwtPlotPickerQwtPlotPicker *picker = new QwtPlotPicker(QwtPlot::xBottom, QwtPlot::yLeft, QwtPicker::PointSelection,QwtPlotPicker:: RubberBand, QwtPicker::AlwaysOn, plot.canvas());picker->setStateMachine(new QwtPickerDragPointMachine()); // 設置選擇模式// 連接信號和槽PickerTracker tracker;connect(picker, SIGNAL(trackerText(const QString &)), &tracker, SLOT(trackerText(const QString &)));connect(picker, SIGNAL(selected(const QPointF &)), &tracker, SLOT(selected(const QPointF &)));// 如果需要平移功能QwtPlotPanner *panner = new QwtPlotPanner(plot.canvas());panner->setMouseButton(Qt::MidButton); // 使用中間按鈕進行平移// 顯示窗口plot.resize(800, 600);plot.show();return app.exec();
}
示例代碼 2
class DistancePicker : public QwtPlotPicker{public:DistancePicker( QWidget* canvas ): QwtPlotPicker( canvas ){setTrackerMode( QwtPicker::ActiveOnly );setStateMachine( new QwtPickerDragLineMachine() );setRubberBand( QwtPlotPicker::PolygonRubberBand );}virtual QwtText trackerTextF( const QPointF& pos ) const QWT_OVERRIDE{QwtText text;const QPolygon points = selection();if ( !points.isEmpty() ){QString num;num.setNum( QLineF( pos, invTransform( points[0] ) ).length() );QColor bg( Qt::white );bg.setAlpha( 200 );text.setBackgroundBrush( QBrush( bg ) );text.setText( num );}return text;}};
setStateMachine 方法
QwtPlotPicker 的 setStateMachine() 方法用于設置選擇器的狀態機,這決定了用戶如何與圖表進行交互。Qwt 提供了幾種預定義的狀態機類,每種狀態機都實現了一種特定的交互模式。以下是 Qwt 中常見的幾種狀態機:
- QwtPickerMachine
這是所有其他狀態機的基礎類,它本身不提供具體的行為,但可以作為自定義狀態機的起點。 - QwtPickerClickPointMachine
這種狀態機允許用戶通過單擊鼠標來選擇一個點。每次點擊都會觸發一個選定點的信號。
? 適用場景:當你只需要用戶在圖表上點擊以選擇單個數據點時使用。 - QwtPickerDragPointMachine
這種狀態機允許用戶通過拖動鼠標來選擇一個點。用戶按下鼠標按鈕并移動到新的位置后釋放按鈕,這個新位置會被視為選定的點。
? 適用場景:適用于需要更精確地選擇或調整圖表上的某個點的情況。 - QwtPickerRectMachine
這種狀態機允許用戶通過拖動鼠標繪制一個矩形區域來選擇多個點。矩形的選擇框會隨著鼠標的移動而更新,直到用戶釋放鼠標按鈕。
? 適用場景:當你需要讓用戶選擇一個矩形區域內的所有數據點時使用。 - QwtPickerPolygonMachine
這種狀態機允許用戶通過連續點擊來創建一個多邊形區域,最終形成一個封閉的多邊形選擇區域。用戶可以通過雙擊或者按下一個特定的鍵(如 Enter)來完成多邊形的選擇。
? 適用場景:適用于復雜形狀的選擇區域,比如非矩形的不規則區域。
setStateMachine 使用示例
#include <QApplication>
#include <QwtPlot>
#include <QwtPlotCurve>
#include <QwtPlotPicker>
#include <QwtPickerMachine>int main(int argc, char *argv[]) {QApplication app(argc, argv);// 創建并配置 QwtPlotQwtPlot plot;plot.setTitle("QwtPlotPicker Example");// 添加一條曲線QwtPlotCurve *curve = new QwtPlotCurve("Sample Curve");QVector<double> xData = {0.0, 1.0, 2.0, 3.0, 4.0};QVector<double> yData = {0.0, 1.0, 4.0, 9.0, 16.0};curve->setSamples(xData, yData);curve->attach(&plot);// 創建并配置 QwtPlotPickerQwtPlotPicker *picker = new QwtPlotPicker(QwtPlot::xBottom, QwtPlot::yLeft, QwtPicker::PointSelection,QwtPlotPicker::RubberBand, QwtPicker::AlwaysOn, plot.canvas());// 設置狀態機picker->setStateMachine(new QwtPickerClickPointMachine()); // 單點選擇// 或者// picker->setStateMachine(new QwtPickerDragPointMachine()); // 拖動選擇點// 或者// picker->setStateMachine(new QwtPickerRectMachine()); // 矩形區域選擇// 或者// picker->setStateMachine(new QwtPickerPolygonMachine()); // 多邊形區域選擇// 顯示窗口plot.resize(800, 600);plot.show();return app.exec();
}
自定義狀態機
如果你的需求超出了上述預定義狀態機的功能,你可以繼承 QwtPickerMachine 類并實現自己的狀態機邏輯。
綜合應用
當你想要創建一個帶有交互功能的圖表時,通常步驟如下:
- 創建 QwtPlot 實例。
- 添加繪圖項,如 QwtPlotCurve 或其他類型的繪圖項。
- 創建并配置 QwtPlotMarker 來添加靜態標記。
- 創建并配置 QwtPlotPicker 來實現交互功能,并根據需要設置選擇模式和事件處理邏輯。
- 連接信號和槽,以便對用戶的交互行為做出響應。
- 如果需要,還可以添加其他交互組件,如 QwtPlotPanner 用于平移功能。