[PyQt] QSplitter and the border between widgets

Jonathan Harper jon at white-walls.net
Wed Oct 12 17:05:45 BST 2011


Timothy:

 

In the absence of source code, let's say your splitter is called "splitter".
To adjust the size of the handle--which seems to be part of your issue--,
use the handleWidth property. Calling splitter.setHandleWidth() with an
integer argument measured in pixels will let you adjust this. You can toy
with this value and how it appears in QtDesigner.

 

As for a "visible" handle, you have two choices: The handle itself created
by a virtual method in QSplitter called createHandle(), returning a
QSplitterHandle. QSplitterHandle follows the current style (see QStyle) in
how it appears. Create a form with a QSplitter in it using QtDesigner, then
preview it with the Cleanlooks style (Form->Preview->Cleanlooks). Cleanlooks
has a visible gripper-albeit an ugly one-,  which I suspect is something
you're looking for. Unfortunately, most styles don't paint anything but a
background for the splitter itself. Drawing a gripper will require
subclassing QSplitter, reimplementing createHandle() to return a subclassed
QSplitterHandle with a reimplemented paintEvent(). Frustrating, I know, but
QStyle follows the style of platforms. If you're on Windows, those are calls
to native Windows APIs, and I assume the same goes for Gnome (QGtkStyle) or
MacOS (QMacStyle).

 

The other aspect to consider about a default QSplitter/QSplitterHandle
combination is that QSplitter inherits QFrame and is typically used with
widgets than inherit QFrame as well (text editors, tree/list widgets, and so
forth). Using setContentsMargins() on the child widgets will put some
padding around the frame, making the handle a bit more obvious.

 

Try working this code into a subclassed QDialog:

 

---------

#I follow the whole from "PyQt4.QtGui import *" instead of "from PyQt4
import QtGui" methodology,

#so assume I did that already and created a subclass of QDialog, and that
this is a setupUi() method I'm demonstrating

#

#Also, I use keyword arguments quite a bit for brevity and clean code. Don't
let this distract you.

 

#assume we're adding other stuff, like a close button to this layout later

layout = QVBoxLayout(parent=self,

                     objectName='layout')

splitter = QSplitter(parent=self,

                     objectName='splitter', 

                     frameShape=QFrame.StyledPanel, 

                     frameShadow=QFrame.Plain)

#for demonstration purposes, we'll make the size fixed

splitter.setFixedSize(QSize(300, 100))

layout.addWidget(splitter)

        

#populate the splitter

widget1 = QFrame(parent=splitter, 

                 objectName='widget1', 

                 frameShape=QFrame.StyledPanel, 

                 frameShadow=QFrame.Sunken)

widget2 = QFrame(parent=splitter, 

                 objectName='widget2', 

                 frameShape=QFrame.StyledPanel, 

                 frameShadow=QFrame.Sunken)

 

#here's the interesting part:

widget1.setContentsMargins(2, 2, 2, 2)

widget2.setContentsMargins(2, 2, 2, 2)

 

 

splitter.addWidget(widget1)

splitter.addWidget(widget2)

 

---------

 

I'm actually working right now on how best to subtly hint that a splitter is
present without making it distracting (look at a piece of software called
XnView as an example of distracting).

 

Hope this helps,

Jonathan Harper

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20111012/c3e630ab/attachment-0001.html>


More information about the PyQt mailing list