title: How to customize QPushButton to only popup menu when clicked around the arrow?
body: <p>I want to add a popup menu to <code>QPushButton</code>, but only popup it when you click near the arrow, if you click other area on the button, it calls the slot connected in main UI. </p>
  
  <p>I know there is <code>QToolButton</code>, and you can set its <code>ToolButtonPopupMode</code> to <code>MenuButtonPopup</code>, but for some reason it looks different than then rest of the button on my UI, I assume I could somehow modify the style of it to make it look exactly like <code>QPushButton</code>, anyway in the end I decided to subclass <code>QPushButton</code> instead.</p>
  
  <p>The problems in the following code are:
  1. How do I get the rect of the arrow, maybe show a dashed rect around the arrow, I thought the "popup menu hotspot" area should be a little bit bigger than the arrow. right now I hardcoded 20px, but I think it should be retrieved from QStyle?</p>
  
  <ol start="2">
  <li><p>[solved] How to make the button look "pressed" when clicked not near the arrow, right now its look does not change, I guess it's because I did not call base class <code>MousePressEvent</code>, because I don't want the menu to popup when clicked elsewhere.</p></li>
  <li><p>How to move the position of the arrow, in my applicaton it is too close to the right edge, how can I move it to the left a little bit?</p></li>
  </ol>
  
  <p><img src="https://i.imgur.com/hObxEm1.jpg" alt="img"></p>
  
  <p>code:</p>
  
  <pre><code>from PyQt4 import QtGui, QtCore
  import sys
  
  
  class MyButton(QtGui.QPushButton):
  
      def __init__(self, parent=None):
          super(MyButton, self).__init__(parent)
  
      def mousePressEvent(self, event):
  
          if event.type() == QtCore.QEvent.MouseButtonPress:
  
              # figure out press location
              pos = event.pos
  
              topRight = self.rect().topRight()
              bottomRight = self.rect().bottomRight()
  
              frameWidth = self.style().pixelMetric(QtGui.QStyle.PM_DefaultFrameWidth)
  
              print topRight, bottomRight, frameWidth
  
              # get the rect from QStyle instead of hardcode numbers here
              arrowTopLeft = QtCore.QPoint(topRight.x()-20, topRight.y())
  
              arrowRect = QtCore.QRect(arrowTopLeft, bottomRight)
  
              if arrowRect.contains(event.pos()):
                  print 'clicked near arrow'
                  # event.accept()
                  QtGui.QPushButton.mousePressEvent(self, event)
              else:
                  print 'clicked outside'
                  # call the slot connected, without popup the menu
                  # the following code now does not make
                  # the button pressed
                  self.clicked.emit(True)
                  event.accept()
  
  class Main(QtGui.QDialog):
  
      def __init__(self, parent=None):
          super(Main, self).__init__(parent)
  
          layout = QtGui.QVBoxLayout()
  
          pushbutton = MyButton('Popup Button')
  
          layout.addWidget(pushbutton)
  
          menu = QtGui.QMenu()
          menu.addAction('This is Action 1', self.Action1)
          menu.addAction('This is Action 2', self.Action2)
          pushbutton.setMenu(menu)
  
          self.setLayout(layout)
  
          pushbutton.clicked.connect(self.button_press)
  
      def button_press(self):
          print 'You pressed button'
  
      def Action1(self):
          print 'You selected Action 1'
  
      def Action2(self):
          print 'You selected Action 2'
  
  
  if __name__ == '__main__':
  
      app = QtGui.QApplication(sys.argv)
      main = Main()
      main.show()
      app.exec_()
  </code></pre>
  
  <p>edit:
  it seems this will stop the menu from poping up if clicked on the left side of the button</p>
  
  <pre><code>else:
      print 'clicked outside'
      self.blockSignals(True)
      QtGui.QPushButton.mousePressEvent(self, event)
      self.blockSignals(False)
  </code></pre>