Skip to content

[FIX] gui: Add a push button class adapted for variable width text #1614

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 30, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion Orange/widgets/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from Orange.widgets.utils import vartype
from Orange.widgets.utils.constants import \
CONTROLLED_ATTRIBUTES, ATTRIBUTE_CONTROLLERS
from Orange.widgets.utils.buttons import VariableTextPushButton
from Orange.util import namegen

YesNo = NoYes = ("No", "Yes")
Expand Down Expand Up @@ -2264,7 +2265,12 @@ def do_commit():
if _is_horizontal(orientation):
b.layout().addSpacing(10)
cb.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
b.button = btn = button(b, master, label, callback=lambda: do_commit())

b.button = btn = VariableTextPushButton(
b, text=label, textChoiceList=[label, auto_label], clicked=do_commit)
if b.layout() is not None:
b.layout().addWidget(b.button)

if not checkbox_label:
btn.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
checkbox_toggled()
Expand Down
61 changes: 61 additions & 0 deletions Orange/widgets/utils/buttons.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from PyQt4.QtGui import QPushButton, QStyle, QStyleOptionButton
from PyQt4.QtCore import Qt, QSize


class VariableTextPushButton(QPushButton):
"""
QPushButton subclass with an sizeHint method to better support settable
variable width button text.

Use this class instead of the QPushButton when the button will
switch the text dynamically while displayed.
"""
def __init__(self, *args, textChoiceList=[], **kwargs):
super().__init__(*args, **kwargs)
self.__textChoiceList = list(textChoiceList)

def setTextChoiceList(self, textList):
"""
Set the list of all `text` string to use for size hinting.

Parameters
----------
textList : List[str]
A list of all different `text` properties that will/can be set on
the push button. This list is used to derive a suitable sizeHint
for the widget.
"""
self.__textChoiceList = textList
self.updateGeometry()

def sizeHint(self):
"""
Reimplemented from `QPushButton.sizeHint`.

Returns
-------
sh : QSize
"""
sh = super().sizeHint()
option = QStyleOptionButton()
self.initStyleOption(option)
style = self.style()
fm = option.fontMetrics
if option.iconSize.isValid():
icsize = option.iconSize
icsize.setWidth(icsize.width() + 4)
else:
icsize = QSize()

for text in self.__textChoiceList:
option.text = text
size = fm.size(Qt.TextShowMnemonic, text)

if not icsize.isNull():
size.setWidth(size.width() + icsize.width())
size.setHeight(max(size.height(), icsize.height()))

sh = sh.expandedTo(
style.sizeFromContents(QStyle.CT_PushButton, option,
size, self))
return sh