當用戶在qslider上的某個地方點擊時,我想讓滑塊跳轉到該位置,而不是步進。這如何實現?QSlider鼠標直接跳轉
回答
嗯,我懷疑Qt是否有直接的功能。
嘗試使用自定義小部件。這應該工作!
嘗試以下邏輯
class MySlider : public QSlider
{
protected:
void mousePressEvent (QMouseEvent * event)
{
if (event->button() == Qt::LeftButton)
{
if (orientation() == Qt::Vertical)
setValue(minimum() + ((maximum()-minimum()) * (height()-event->y()))/height()) ;
else
setValue(minimum() + ((maximum()-minimum()) * event->x())/width()) ;
event->accept();
}
QSlider::mousePressEvent(event);
}
};
對於水平滑塊值將無法正確計算。我建議這樣的變體:'setValue(minimum()+(maximum() - minimum())*(static_cast
感謝您的代碼,但在我的情況下,我需要添加一個「+1」才能工作:「setValue(minimum()+((maximum() - minimum()+ 1)*(height() - event-> y() ))/ height());「 – Alex
一個簡單的方法是從QSlider
導出並用mousePressEvent(....)
重新實現以使用setSliderPosition(int)
來設置標記位置。
我一直在試圖和網絡搜索這一點,並期待的Qt的更聰明的辦法這樣做,不幸的是有沒有大的幫助(可能是我沒有搜索正確)
以及我已經在Qt的創建者這樣做:
- 在報頭添加eventFilter(需要的QObject和QEvent的作爲參數)(布爾返回類型)
- 在構造函數中初始化..for例如..如果你的滑塊是HSlider然後 ui-> HSlider-> installEventFilter(this);
定義:
a。檢查對象是否是您的滑塊類型:
ui->HSlider == Object
b。檢查鼠標點擊事件是這樣的:
QEvent::MouseButtonPress == event->type
c。如果所有道次以上意味着u必須抓住滑動件鼠標事件做類似:在定義:
ui->HSlider->setValue(Qcursor::pos().x() - firstval); return QMainWindow::eventFilter(object, event);
注:fistVal:可通過打印cursur位置0 =滑塊的初始位置被取出(與QCursor::pos().x()
幫助)
希望這有助於
我需要這也並試圖spyke解決方案,但它缺少兩樣東西:
- 倒外觀
- 柄採摘(當鼠標移動到手柄,直接跳轉是沒有必要的)
所以,這裏的審查代碼:
void MySlider::mousePressEvent (QMouseEvent * event)
{
QStyleOptionSlider opt;
initStyleOption(&opt);
QRect sr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
if (event->button() == Qt::LeftButton &&
sr.contains(event->pos()) == false)
{
int newVal;
if (orientation() == Qt::Vertical)
newVal = minimum() + ((maximum()-minimum()) * (height()-event->y()))/height();
else
newVal = minimum() + ((maximum()-minimum()) * event->x())/width();
if (invertedAppearance() == true)
setValue(maximum() - newVal);
else
setValue(newVal);
event->accept();
}
QSlider::mousePressEvent(event);
}
幾乎是優秀的。如果特殊位置已經完成,我只需要移除傳遞給基類的'event'。 –
這應該是正確答案,無需修改即可使用。 – Andrew
下面的代碼實際上是一個黑客,但它沒有子類別QSlider工作正常。您需要做的唯一事情就是將QSlider valueChanged信號連接到您的容器。
注1:必須設置一個pageStep> 0在滑塊
注2:它僅適用於一個水平,由左到右滑塊(你應該改變的「sliderPosUnderMouse」計算與垂直方向的工作或倒立的外觀)
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
// ...
connect(ui->mySlider, SIGNAL(valueChanged(int)),
this, SLOT(mySliderValueChanged(int)));
// ...
}
void MainWindow::mySliderValueChanged(int newPos)
{
// Make slider to follow the mouse directly and not by pageStep steps
Qt::MouseButtons btns = QApplication::mouseButtons();
QPoint localMousePos = ui->mySlider->mapFromGlobal(QCursor::pos());
bool clickOnSlider = (btns & Qt::LeftButton) &&
(localMousePos.x() >= 0 && localMousePos.y() >= 0 &&
localMousePos.x() < ui->mySlider->size().width() &&
localMousePos.y() < ui->mySlider->size().height());
if (clickOnSlider)
{
// Attention! The following works only for Horizontal, Left-to-right sliders
float posRatio = localMousePos.x()/(float)ui->mySlider->size().width();
int sliderRange = ui->mySlider->maximum() - ui->mySlider->minimum();
int sliderPosUnderMouse = ui->mySlider->minimum() + sliderRange * posRatio;
if (sliderPosUnderMouse != newPos)
{
ui->mySlider->setValue(sliderPosUnderMouse);
return;
}
}
// ...
}
Massimo Callegari的答案几乎是正確的,但newVal的計算忽略了滑塊手柄的寬度。當您嘗試在滑塊末尾附近單擊時出現此問題。
以下代碼修復此爲水平滑塊
double halfHandleWidth = (0.5 * sr.width()) + 0.5; // Correct rounding
int adaptedPosX = event->x();
if (adaptedPosX < halfHandleWidth)
adaptedPosX = halfHandleWidth;
if (adaptedPosX > width() - halfHandleWidth)
adaptedPosX = width() - halfHandleWidth;
// get new dimensions accounting for slider handle width
double newWidth = (width() - halfHandleWidth) - halfHandleWidth;
double normalizedPosition = (adaptedPosX - halfHandleWidth)/newWidth ;
newVal = minimum() + ((maximum()-minimum()) * normalizedPosition);
缺少分號,不得不做6個字符編輯所以增加了另一個註釋 – Chance
我認爲,
在將QStyle :: sliderValueFromPosition()函數可以被使用。具有@spyke @Massimo CALLEGARI和@Ben(滑塊位置wasnt正確的整個區域)的所有版本問題後
http://qt-project.org/doc/qt-5/qstyle.html#sliderValueFromPosition
我發現QSlider源代碼中的一些Qt樣式的功能:QStyle::SH_Slider_AbsoluteSetButtons
。
你必須創建一個新的將QStyle它可以是一個很煩人的,或者你使用ProxyStyle
作爲http://www.qtcentre.org/threads/9208-QSlider-step-customize?p=49035#post49035
顯示用戶JPN我添加了另一個構造和固定一個錯字,但所用的其餘部分原始的源代碼。
#include <QProxyStyle>
class MyStyle : public QProxyStyle
{
public:
using QProxyStyle::QProxyStyle;
int styleHint(QStyle::StyleHint hint, const QStyleOption* option = 0, const QWidget* widget = 0, QStyleHintReturn* returnData = 0) const
{
if (hint == QStyle::SH_Slider_AbsoluteSetButtons)
return (Qt::LeftButton | Qt::MidButton | Qt::RightButton);
return QProxyStyle::styleHint(hint, option, widget, returnData);
}
};
現在你可以設置中的滑動構造的滑蓋風格(如果你的滑塊從QSlider派生):
setStyle(new MyStyle(this->style()));
還是應該以這種方式工作,如果它是一個標準的QSlider:
standardSlider.setStyle(new MyStyle(standardSlider->style()));
使您在使用該元素的原有風格,但如果QStyle::SH_Slider_AbsoluteSetButtons
「屬性」是問你回來,只要你想)
也許你必須在滑塊刪除時銷燬這些代理風格,尚未經過測試。
這應該是被接受的答案。 – maxschlepzig
是的,這是正確的答案。 – ens
也希望能夠欣賞這個答案。 QSliders已經在macOS中以這種方式表現出來了,所以我認爲必須有比QSlider子類化更優雅的解決方案才能在Windows中獲得相同的行爲。有意義的是,這樣的解決方案涉及使用QStyle/QProxyStyle。 – GuyGizmo
下面是使用Python QStyle.sliderValueFromPosition()一個簡單的實現:基於周邊的意見
class JumpSlider(QtGui.QSlider):
def mousePressEvent(self, ev):
""" Jump to click position """
self.setValue(QtGui.QStyle.sliderValueFromPosition(self.minimum(), self.maximum(), ev.x(), self.width()))
def mouseMoveEvent(self, ev):
""" Jump to pointer position while moving """
self.setValue(QtGui.QStyle.sliderValueFromPosition(self.minimum(), self.maximum(), ev.x(), self.width()))
這是要走的路!它的工作原理很簡單,而且與操作系統無關。 – zephyr
我的最終實現:
class ClickableSlider : public QSlider {
public:
ClickableSlider(QWidget *parent = 0) : QSlider(parent) {}
protected:
void ClickableSlider::mousePressEvent(QMouseEvent *event) {
QStyleOptionSlider opt;
initStyleOption(&opt);
QRect sr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
if (event->button() == Qt::LeftButton &&
!sr.contains(event->pos())) {
int newVal;
if (orientation() == Qt::Vertical) {
double halfHandleHeight = (0.5 * sr.height()) + 0.5;
int adaptedPosY = height() - event->y();
if (adaptedPosY < halfHandleHeight)
adaptedPosY = halfHandleHeight;
if (adaptedPosY > height() - halfHandleHeight)
adaptedPosY = height() - halfHandleHeight;
double newHeight = (height() - halfHandleHeight) - halfHandleHeight;
double normalizedPosition = (adaptedPosY - halfHandleHeight)/newHeight ;
newVal = minimum() + (maximum()-minimum()) * normalizedPosition;
} else {
double halfHandleWidth = (0.5 * sr.width()) + 0.5;
int adaptedPosX = event->x();
if (adaptedPosX < halfHandleWidth)
adaptedPosX = halfHandleWidth;
if (adaptedPosX > width() - halfHandleWidth)
adaptedPosX = width() - halfHandleWidth;
double newWidth = (width() - halfHandleWidth) - halfHandleWidth;
double normalizedPosition = (adaptedPosX - halfHandleWidth)/newWidth ;
newVal = minimum() + ((maximum()-minimum()) * normalizedPosition);
}
if (invertedAppearance())
setValue(maximum() - newVal);
else
setValue(newVal);
event->accept();
} else {
QSlider::mousePressEvent(event);
}
}
};
我也遇到了這個問題。我的解決方案如下所示。
slider->installEventFilter(this);
---
bool MyDialog::eventFilter(QObject *object, QEvent *event)
{
if (object == slider && slider->isEnabled())
{
if (event->type() == QEvent::MouseButtonPress)
{
auto mevent = static_cast<QMouseEvent *>(event);
qreal value = slider->minimum() + (slider->maximum() - slider->minimum()) * mevent->localPos().x()/slider->width();
if (mevent->button() == Qt::LeftButton)
{
slider->setValue(qRound(value));
}
event->accept();
return true;
}
if (event->type() == QEvent::MouseMove)
{
auto mevent = static_cast<QMouseEvent *>(event);
qreal value = slider->minimum() + (slider->maximum() - slider->minimum()) * mevent->localPos().x()/slider->width();
if (mevent->buttons() & Qt::LeftButton)
{
slider->setValue(qRound(value));
}
event->accept();
return true;
}
if (event->type() == QEvent::MouseButtonDblClick)
{
event->accept();
return true;
}
}
return QDialog::eventFilter(object, event);
}
您也可以重寫這些QSlider的事件處理程序。
QSlider::mousePressedEvent
QSlider::mouseMoveEvent
QSlider::mouseDoubleClickEvent
- 1. Django直接跳轉到div
- 2. 鏈接繼續跳躍點擊鼠標
- 3. Visual Studio中聯彙編直接跳轉
- 4. 鼠標懸停鼠標一直執行
- 5. 瀏覽器跳過「if」,「else if」,直接跳轉到「else」語句
- 6. 防反跳鼠標滾輪
- 7. 使用QQuaternion和QSlider旋轉
- 8. 鼠標跳躍,當我輸入標籤
- 9. 鼠標旋轉
- 10. 跳轉和跳轉和鏈接不同
- 11. objdump的輸出中的直接和間接調用/跳轉
- 12. visual studio 2010 - 用鼠標跳轉到方法定義
- 13. 視差滾動 - 使用鼠標滾輪時跳轉
- 14. 用鼠標拖動時圖像跳轉到中心點
- 15. 跳轉到函數定義在Emacs通過鼠標點擊
- 16. CSS背景縮放動畫在鼠標上跳轉
- 17. tmux鼠標複製模式跳轉到底部
- 18. 鼠標旋轉div
- 19. 翻轉NSView鼠標座標
- 20. HTML跳轉鏈接 - 如何創建跳轉鏈接
- 21. 讓鼠標指針做一個超跳?
- 22. IE8李菜單跳躍鼠標懸停
- 23. 鼠標點擊面板跳過點擊
- 24. 如何讓滑塊控件直接在windows phone中跳轉?
- 25. 在LLVM中直接跳轉的分支指令
- 26. 直接跳轉到另一個C++函數
- 27. 直接跳轉到'git add -i'補丁命令(5)
- 28. jquery.mmenu如何直接跳轉到一個子頁
- 29. .nextLine()直接跳轉到下一個輸出
- 30. 嘗試直接在鏈表跳轉到一個節點
見Micka的答案下面,而不是一個簡單的解決方案公認的答案。 –
請注意,滑塊的默認行爲是平臺特定的。例如,在MacOS上,滑塊直接跳到鼠標點擊的位置。 – normanius