2010-03-30 20 views

risposta

25

Dal momento che l'QSplitterHandle (che è ciò che la maggior parte della gente pensa come il 'splitter') è derivato da QWidget, è possibile aggiungere altri widget ad essa . Ecco cosa ho fatto per risolvere questo problema esatto in passato:

// Now add the line to the splitter handle 
// Note: index 0 handle is always hidden, index 1 is between the two widgets 
QSplitterHandle *handle = pSplitter->handle(1); 
QVBoxLayout *layout = new QVBoxLayout(handle); 
layout->setSpacing(0); 
layout->setMargin(0); 

QFrame *line = new QFrame(handle); 
line->setFrameShape(QFrame::HLine); 
line->setFrameShadow(QFrame::Sunken); 
layout->addWidget(line); 

Questo aggiunge una linea incassata alla maniglia splitter. Puoi, ovviamente, scegliere un altro stile per il fotogramma line o utilizzare qualcosa di completamente diverso come il widget che aggiungi al quadratino di splitter.

+0

Grazie mille :)! – Narek

+0

Questo è fantastico. Vorrei solo aggiungere che preferisco un QHBoxLayout perché quindi posso assegnare un 'maximumWidth' (per gli splitter orizzontali) alla linea orizzontale. – Phlucious

+0

Upvoted perché funziona, ma sembra davvero una soluzione maldestra per un bug Qt ... –

7

Questo vale per ogni splitter almeno con WinXP e il Luna Luna predefinito (il passaggio al classico risolve il problema). Se vuoi stare con Luna, puoi cambiare il modo in cui gli splitter sono resi, ad es. cambiando il colore di sfondo della maniglia.

int main(int argc, char *argv[]) { 

    QApplication a(argc, argv); 
    a.setStyleSheet("QSplitter::handle { background-color: gray }"); 
    MainWindow w; 
    w.show(); 
    return a.exec(); 
} 

Si possono trovare maggiori sui fogli di stile Qt a https://doc.qt.io/qt-5/stylesheet-reference.html

+0

Grazie. Questo cambia colore ma vorrei cambiare il sollievo dello splitter. È possibile? – Narek

+0

Il comportamento predefinito dello splitter in Windows è quello di disegnare il colore di sfondo. Questo è un problema quando i componenti splittati hanno anche il colore bg di default (QWidget). Il modo di Windows è di dare loro un colore diverso e/o un bordo incavato (QFrame supporta i bordi). Se si desidera utilizzare lo scarico, è necessario modificare lo stile (dimenticare il foglio di stile). Usa setStyle() per cambiare lo stile. I rilievi sono supportati per es. di QPlastiqueStyle. È possibile applicare setStyle() all'oggetto QApplication o solo allo splitter (non preferito). Vorrei proporre la soluzione nativa menzionata per prima. – merula

+0

È possibile eseguire l'override di QSplitter :: createHandle() per restituire l'handle con il disegno personalizzato –

8

L'ho basato sul codice precedente ma gestisce entrambi gli orientamenti dello splitter. Ho preferito solo il ridimensionamento non opaco e i bambini non pieghevoli. L'impugnatura è composta da tre linee parallele. Puoi giocare con la larghezza della maniglia, ma la presa a 7 sembra buona su Windows; non ho controllato in Linux o Mac.

void helper::decorateSplitter(QSplitter* splitter, int index) 
{ 
    Q_ASSERT(splitter != NULL); 

    const int gripLength = 15; 
    const int gripWidth = 1; 
    const int grips = 3; 

    splitter->setOpaqueResize(false); 
    splitter->setChildrenCollapsible(false); 

    splitter->setHandleWidth(7); 
    QSplitterHandle* handle = splitter->handle(index); 
    Qt::Orientation orientation = splitter->orientation(); 
    QHBoxLayout* layout = new QHBoxLayout(handle); 
    layout->setSpacing(0); 
    layout->setMargin(0); 

    if (orientation == Qt::Horizontal) 
    { 
     for (int i=0;i<grips;++i) 
     { 
      QFrame* line = new QFrame(handle); 
      line->setMinimumSize(gripWidth, gripLength); 
      line->setMaximumSize(gripWidth, gripLength); 
      line->setFrameShape(QFrame::StyledPanel); 
      layout->addWidget(line); 
     } 
    } 
    else 
    { 
     //this will center the vertical grip 
     //add a horizontal spacer 
     layout->addStretch(); 
     //create the vertical grip 
     QVBoxLayout* vbox = new QVBoxLayout; 
     for (int i=0;i<grips;++i) 
     { 
      QFrame* line = new QFrame(handle); 
      line->setMinimumSize(gripLength, gripWidth); 
      line->setMaximumSize(gripLength, gripWidth); 
      line->setFrameShape(QFrame::StyledPanel); 
      vbox->addWidget(line); 
     } 
     layout->addLayout(vbox); 
     //add another horizontal spacer 
     layout->addStretch(); 
    } 
} 
+0

Probabilmente la migliore soluzione qui anche usando Qt5.6. Grazie! – Plouff

+0

Doveva impostare 'gripWidth = 2' affinché i grip fossero visibili (aspetto Win7 Classic).Altrimenti bella soluzione per un problema che avrebbe dovuto essere risolto in Qt anni fa. – DerManu

0

È possibile sottoclasse QSplitter e sovrascrivere è protected virtual QSplitterHandle * QSplitter::createHandle() di restituire tutto ciò che ti rende felice.

Ad esempio, da tale metodo sovraccarico è possibile restituire sottoclasse di QSplitterHandle con il disegno personalizzato.

-1

Grazie alla risposta di Merula ... Ho provato questo e ora i miei splitter sono visibili e sembrano molto belli senza sembrare invadenti. Questo codice è per Python usando PyQt o PySide.

app = QtGui.QApplication(sys.argv) 
app.setStyle("Plastique") # set style (using this style shows splitters! :) 
+0

che lingua è questa? Questo non sembra C++ –

+0

oops .. mi dispiace questo è python usando pyqt o pyside – panofish