How do you provide size hints for custom widgets?

514 views
Skip to first unread message

Jason Sachs

unread,
Jan 2, 2014, 10:50:22 AM1/2/14
to en...@googlegroups.com
Post topic kinda says it all... I'm adding a custom widget, and I can't figure out how to have that widget provide a size hint for layout purposes. Could someone help me? I can't figure out how enaml is doing it at present.

I've looked at the constraints_widget classes

but can't figure out how it works, for PushButton for example. Is this hooking into something that's builtin to QT's own layout methods?

Jason Sachs

unread,
Jan 2, 2014, 11:00:05 AM1/2/14
to en...@googlegroups.com
Additional info, if it helps -- my specific case is that I'm adapting a QTableView. I'm running into this exact problem: http://stackoverflow.com/questions/8766633/how-to-determine-the-correct-size-of-a-qtablewidget
except it's in enaml, not C.
Message has been deleted

Jason Sachs

unread,
Jan 2, 2014, 12:23:54 PM1/2/14
to en...@googlegroups.com
Ah. I think I figured it out; the QtConstraintsWidget automatically calls the sizeHint() method of its widget member. It looks like QTableView's sizeHint() method is lame, so I overrode it:

class QJTableView(QTableView):
    '''Subclass QTableView to customize size hints'''
    def sizeHint(self):
        x_fudge_width = 2
        y_fudge_width = 2
        # No idea where these magic numbers come from, or how they vary on different systems
        xfull = self.horizontalHeader().length() + self.verticalHeader().sizeHint().width() + x_fudge_width
        yfull = self.verticalHeader().length()   + self.horizontalHeader().sizeHint().height() + y_fudge_width
        # If they are smaller, the scrollbars appear, and then we'd need to add room for the scrollbars,
        # in which case the scrollbars would disappear.
        x = xfull + self.verticalScrollBar().sizeHint().width()
        # Make room for up to the first 12 columns 
        y = self.horizontalHeader().sizeHint().height() + y_fudge_width
        m = self.model()
        if m is not None:
            y += sum(self.rowHeight(r) for r in xrange(min(12,m.rowCount())))
        sz = QSize(x,y)
        return sz

Chris Colbert

unread,
Jan 2, 2014, 2:14:48 PM1/2/14
to en...@googlegroups.com
Yep, you got it. Reimplement the 'sizeHint' method on your custom Qt widget. Enaml calls that automatically when it generates the constraints for the size hint.

Chris Colbert

unread,
Jan 2, 2014, 2:16:49 PM1/2/14
to en...@googlegroups.com
Although, you should know that the 'sizeHint' method is called *often* by Qt itself, so your implementation should be as fast as possible. Since you are summing across all rows, your method will be slow if the number of rows is large. You should consider caching the computed size hint and only recompute it when the number of rows in the table has changed.

Jason Sachs

unread,
Jan 2, 2014, 3:19:42 PM1/2/14
to en...@googlegroups.com
OK, thanks for the tip. I'm not worried about the slow response in this case; I only compute the size of the table's rows up through row 12. (even if there are 1000 rows in the table)
Reply all
Reply to author
Forward
0 new messages