user1490547
user1490547

Reputation: 31

Attach a QToolButton to bottom right corner of the parent QWidget

I am faced with this problem and being a Qt noob am not able to fix it.

Basically, I instantiated a QToolButton and parented it to QTreeWidget. The QTreeWidget is inside a vertical layout and when I try to change the position of the tool button inside the QTreeWidget using QTreeWidget.size() it gives me very unexpected and wrong results.

Can anyone help me with this? Will deeply appreciate the help. Thanks!

Upvotes: 1

Views: 2643

Answers (2)

wedesoft
wedesoft

Reputation: 2989

I think it is possible to set a horizontal box layout for the tree widget then add a spacer and the tool button with bottom alignment.

Upvotes: 0

jdi
jdi

Reputation: 92569

You haven't posted any examples of what you are actually doing, but here is how to attach a button to the lower right of the tree widget:

Edit: I have replaced my answer after seeing that you want to composite the widget OVER the tree

Using an eventFilter

from PyQt4 import QtCore, QtGui

class Widget(QtGui.QWidget):

    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        self.resize(640,480)

        self.layout = QtGui.QVBoxLayout(self)
        self.layout.setSpacing(0)

        self.tree = QtGui.QTreeWidget(self)
        self.tree.installEventFilter(self)
        self.layout.addWidget(self.tree)

        self.button = QtGui.QToolButton(self.tree)
        self.button.setText("FOO")
        self.button.setMinimumSize(100, 30)

    def eventFilter(self, obj, event):
        if obj is self.tree and event.type() == event.Resize:
            self.alignTreeButton()       
        return False

    def alignTreeButton(self):
        padding = QtCore.QSize(5,5) # optional
        newSize = self.tree.size() - self.button.size() - padding
        self.button.move(newSize.width(), newSize.height())          

if __name__ == "__main__":
    app = QtGui.QApplication([])
    w = Widget()
    w.show()
    w.raise_()
    app.exec_()

The button is just parented to the tree, and we install the event filter on the tree to catch resize events. Once the tree is resized, we take its size, subtract the size of the button, and then move the button.

Using composition

I believe its more efficient to actually subclass the QTreeWidget, compose it with the QToolButton as a member, and then overload the resizeEvent() locally to handle the resize. First off this makes the behavior handling local to the TreeWidget, which is cleaner. Also, I believe it reduces the overhead that an EventFilter would add to your main window. The eventFiler would be a python callable that is called many more times because of it handling every event for the object. Whereas the local resizeEvent() for the TreeWidget is only called during the resize.

class Widget(QtGui.QWidget):

    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        self.resize(640,480)

        self.layout = QtGui.QVBoxLayout(self)
        self.layout.setSpacing(0)

        self.tree = TreeWidget(self)
        self.layout.addWidget(self.tree)     


class TreeWidget(QtGui.QTreeWidget):

    def __init__(self, *args, **kwargs):
        super(TreeWidget, self).__init__(*args, **kwargs)
        self.button = QtGui.QToolButton(self)
        self.button.setText("FOO")
        self.button.setMinimumSize(100, 30)

    def resizeEvent(self, event):
        super(TreeWidget, self).resizeEvent(event)
        self.alignTreeButton()

    def alignTreeButton(self):
        padding = QtCore.QSize(5,5) # optional
        newSize = self.size() - self.button.size() - padding
        self.button.move(newSize.width(), newSize.height())  

Upvotes: 3

Related Questions