PySide получить ширину кнопки со стрелкой в ​​QSpinBox - PullRequest
0 голосов
/ 21 января 2019

Есть ли способ определить ширину кнопок со стрелками в qspinbox? Я пытаюсь перезаписать событие контекстного меню, и я хочу, чтобы мое пользовательское событие происходило только в том случае, если пользователь щелкает правой кнопкой мыши по кнопке со стрелкой, в противном случае я хочу, чтобы появилось обычное контекстное меню.

Сейчас я просто жестко кодирую значение 20, которое не идеально.

import sys
import os
from PySide import QtGui, QtCore

class MySpinner(QtGui.QSpinBox):
    def __init__(self, parent=None):
        super(MySpinner, self).__init__(parent)
        self.setAccelerated(False)
        self.setRange(-1000,1000)
        self.setSingleStep(1)
        self.setValue(300)

    def contextMenuEvent(self, event):
        if event.pos().x() > self.rect().right()-20:
            self.setValue(50)
            self.selectAll()
        else:
            super(self.__class__, self).contextMenuEvent(event)


class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.resize(300, 200)

        grid = QtGui.QVBoxLayout()
        grid.addWidget(MySpinner())
        content = QtGui.QWidget()
        content.setLayout(grid)
        self.setCentralWidget(content)



def main():
    app = QtGui.QApplication(sys.argv)
    ex = MainWindow()
    ex.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

1 Ответ

0 голосов
/ 21 января 2019

Вместо получения ширины необходимо только получить SubControl, чтобы знать, была ли она нажата на одной из кнопок со стрелками:

def contextMenuEvent(self, event):
    opt = QtGui.QStyleOptionSpinBox()
    self.initStyleOption(opt)
    opt.subControls = QtGui.QStyle.SC_All
    hoverControl = self.style().hitTestComplexControl(QtGui.QStyle.CC_SpinBox, opt, event.pos(), self)
    if hoverControl == QtGui.QStyle.SC_SpinBoxUp:
        print("up")
    elif hoverControl == QtGui.QStyle.SC_SpinBoxDown:
        print("down")
    else:
        super(self.__class__, self).contextMenuEvent(event)

Если вы хотите получить QRect каждого субконтроля, вам следуетиспользуйте

# up
rect_up = self.style().subControlRect(QtGui.QStyle.CC_SpinBox, opt, QtGui.QStyle.SC_SpinBoxUp, self)
# down
rect_down = self.style().subControlRect(QtGui.QStyle.CC_SpinBox, opt, QtGui.QStyle.SC_SpinBoxDown, self)

Другой вариант:

def contextMenuEvent(self, event):
    opt = QtGui.QStyleOptionSpinBox()
    self.initStyleOption(opt)
    r = QtCore.QRect()
    for sc in (QtGui.QStyle.SC_SpinBoxUp, QtGui.QStyle.SC_SpinBoxDown):
        r= r.united(self.style().subControlRect(QtGui.QStyle.CC_SpinBox, opt, sc, self))
    if r.contains(event.pos()):
        print("arrow")
    else:
        super(self.__class__, self).contextMenuEvent(event)
...