Wie man ein erweiterbares / kollabierbares Bereichs-Widget in QT erstellt
Ich möchte erstellen Sie eine benutzerdefinierte widget von QT mit den folgenden Eigenschaften:
- Es ist ein container
- Es kann aufgefüllt werden mit jeder QT-layout
- Es kann innerhalb eines QT-layout
- Eine Schaltfläche ermöglicht das ausblenden/Fach vertikal um den Inhalt, so dass nur der button sichtbar ist, all die enthaltenen layout ist unsichtbar.
- Die Schaltfläche ermöglicht es zu erweitern/zu entfalten es wieder auf die Größe des layout-Inhalt.
- Die Erweiterung und die einstürzung basiert auf Größen, die (nicht auf - /ausblenden) ermöglicht die animation.
- Verwendbar in QDesigner
Um eine Idee, hier ist ein Bild von einem ähnlichen widget (nicht QT):
Ich habe bereits einen Rahmen, der richtig funktioniert und ausgesetzt in QDesigner. Ich brauche nun, um es zu erweitern/zu reduzieren, was offenbar nicht so einfach.
Habe ich versucht zu spielen mit resize(), sizePolicy(), sizeHint (), aber das funktioniert nicht:
Wenn der Rahmen brach ich bekam folgende Werte:
sizeHint: (500,20)
size : (500,20)
closestAcceptableSize: (518,150)
Painted size: (518, 150)
QLayout::closestAcceptableSize ist nicht Teil des widget, so kann ich es nicht ändern.
Jeden Hinweis oder/und code-Schnipsel zu erreichen?
BEARBEITET:
Hier ein einfaches Beispiel. Ich entfernte alle außer notwendig.
main.cpp Beispiel
#include <QWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include "section.hpp"
using namespace myWidgets;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//Create the main Window
QWidget window;
window.resize(500,500);
window.setStyleSheet("QPushButton:{background-color:rgba(128,128,128,192);}");
//Create the main window layout
QVBoxLayout topLayout(&window);
QWidget *w1 = new QWidget();
w1->setStyleSheet("background-color:rgba(128,128,128,192);");
topLayout.addWidget(w1);
Section section(&window);
topLayout.addWidget(§ion);
QVBoxLayout inLayout(§ion);
QPushButton *button = new QPushButton();
button->setMinimumHeight(100);
inLayout.addWidget(button);
QWidget *w2 = new QWidget();
w2->setStyleSheet("background-color:rgba(128,128,128,192);");
topLayout.addWidget(w2);
window.show();
return a.exec();
}
Abschnitt.hpp
#ifndef SECTION_HPP
#define SECTION_HPP
#include <QPushButton> //for the expand/collapse button
#include <QtDesigner/QDesignerExportWidget>
#include <QLayout>
#include <QPainter>
#include <QPaintEvent>
#include <QDebug>
//Compatibility for noexcept, not supported in vsc++
#ifdef _MSC_VER
#define noexcept throw()
#endif
#if defined SECTION_BUILD
#define SECTION_BUILD_DLL_SPEC Q_DECL_EXPORT
#elif defined SECTION_EXEC
#define SECTION_BUILD_DLL_SPEC
#else
#define SECTION_BUILD_DLL_SPEC Q_DECL_IMPORT
#endif
namespace myWidgets
{
class SECTION_BUILD_DLL_SPEC Section : public QWidget
{
Q_OBJECT
Q_PROPERTY( bool is_expanded MEMBER isExpanded)
public:
//Constructor, standard
explicit Section( QWidget *parent=0 ): QWidget(parent),
expandButton(this)
{
expandButton.resize(20,20);
expandButton.move(0,0);
expandButton.connect(&expandButton, &QPushButton::clicked,
this, &Section::expandCollapseEvent);
QMargins m= contentsMargins();
m.setTop(m.top()+25);
setContentsMargins(m);
//setSizePolicy(sizePolicy().horizontalPolicy(), QSizePolicy::Minimum);
}
virtual void expand( bool expanding ) noexcept
{
resize(sizeHint());
isExpanded = expanding;
updateGeometry();
qDebug() << (isExpanded? "expanded":"collapsed") << sizeHint() << QWidget::size() <<
parentWidget()->layout()->closestAcceptableSize(this, size());
}
virtual QSize sizeHint() const noexcept override
{
if (isExpanded) return QSize(layout()->contentsRect().width(),
layout()->contentsRect().height());
else return QSize(layout()->contentsRect().width(), 20);
}
//Implement custom appearance
virtual void paintEvent(QPaintEvent *e) noexcept override
{
(void) e; //TODO: remove
QPainter p(this);
p.setClipRect(e->rect());
p.setRenderHint(QPainter::Antialiasing );
p.fillRect(e->rect(), QColor(0,0,255,128));
}
protected:
//on click of the expandButton, collapse/expand this widget
virtual void expandCollapseEvent() noexcept
{
expand(!isExpanded);
}
bool isExpanded = true; //whenever the section is collapsed(false) or expanded(true)
QPushButton expandButton; //the expanding/collapsing button
};
}
#endif //SECTION_HPP
InformationsquelleAutor der Frage Adrian Maire | 2015-09-09
Du musst angemeldet sein, um einen Kommentar abzugeben.
Stolperte ich über das gleiche problem und löste es durch die Umsetzung der Klapp-widget als ein
QScrollArea
deren maximale Höhe ist animiert durch eineQPropertyAnimation
.Da ich aber nicht verwenden QDesigner, kann ich dir nicht sagen, ob es funktioniert es.
Ich habe noch ein problem: Statt nur erweitert in Richtung der unteren Richtung, die Klapp-widgets erweitern kann in Richtung der Ober-und Unterseite. Dies kann die Ursache für widgets, die sich über ihm befindet, um zu schrumpfen, wenn Sie noch nicht erreicht Ihre minimale Höhe, noch. Aber das ist wirklich ein detail im Vergleich zu der Tatsache, dass wir haben, um das Ding selbst...
Spoiler.h
Spoiler.cpp
Wie es zu benutzen:
InformationsquelleAutor der Antwort x squared
Obwohl das alte fand ich diesen thread hilfreich. Allerdings arbeite ich in python, also musste ich konvertieren der C++ - code.
Nur für den Fall, jemand ist auf der Suche nach einer python-version von x-squared Lösung. Hier ist mein Hafen:
InformationsquelleAutor der Antwort Erotemic
Ich weiß, das ist nicht ein guter Weg, um eine Frage zu beantworten, nur mit einem link, aber ich denke, dieser blog-post ist durchaus relevant:
http://www.fancyaddress.com/blog/qt-2/create-something-like-the-widget-box-as-in-the-qt-designer/
Es basiert auf QTreeWidget, und nutzt seine /Zuklappen-features, die bereits implementiert sind.
Es wird erklärt, wie widgets können Hinzugefügt werden, um das tree-widget-Elemente, und wie Sie eine Schaltfläche für das aus - /einblenden.
Natürlich alle Kredit geht für die post-Autors.
InformationsquelleAutor der Antwort LoPiTaL
Ich habe gegraben durch die ausgezeichnete Zeiger zur Verfügung gestellt von @LoPiTal und baute es zu PyQt5 (Python ist3). Ich denke, es ist sehr elegant.
In den Fall, jemand ist auf der Suche nach einem PyQt-Lösung, hier ist mein code:
InformationsquelleAutor der Antwort CodingCat
Die Lösung, die ich angewendet, ist die Verwendung der Eigenschaft MaximumSize des widgets zu begrenzen die Höhe zusammengeklappt.
Das größte problem ist zu wissen, das die aufgeklappt Höhe zusammengeklappt zur korrekten animation Schritt. Diese wurde nicht gelöst und ich machen derzeit eine animation mit einem fix-Höhe Schritt (die ich zu einem angemessenen Wert in Bezug auf die erwartete Höhe des Fensters).
InformationsquelleAutor der Antwort Adrian Maire