Ich habe gerade angefangen, an einem neuen C++/Qt-Projekt zu arbeiten. Es wird ein MDI-basiertes IDE mit angedockten Widgets für Dinge wie den Dateibaum, den Objektbrowser, die Compiler-Ausgabe usw. sein Verkleinern Sie programmgesteuert eine QDockWidget
. Mit diesem Snippet wird beispielsweise mein unteres Dock-Fenster "Build Information" erstellt:
m_compilerOutput = new QTextEdit;
m_compilerOutput->setReadOnly(true);
dock = new QDockWidget(tr("Build Information"), this);
dock->setWidget(m_compilerOutput);
addDockWidget(Qt::BottomDockWidgetArea, dock);
Nach dem Start sieht mein Programm so aus (bedenke den frühen Entwicklungsstand):
Ich möchte jedoch, dass es so aussieht:
Ich kann nicht scheinen, dass das passiert. In der Qt-Referenz auf QDockWidget heißt es:
Benutzerdefinierte Größenhinweise, minimale und maximale Größen und Größenrichtlinien sollten im untergeordneten Widget implementiert werden. QDockWidget respektiert sie und passt seine eigenen Einschränkungen an, um den Rahmen und den Titel einzuschließen. Größenbeschränkungen sollten nicht für das QDockWidget selbst festgelegt werden, da sie sich abhängig davon ändern, ob es angedockt ist
Dies deutet darauf hin, dass eine Methode, um dies zu tun, darin besteht, QTextEdit
als Unterklasse anzugeben und die Methode sizeHint()
zu überschreiben. Ich würde es jedoch vorziehen, dies nicht nur zu diesem Zweck zu tun, noch habe ich versucht, dies als funktionierende Lösung zu finden.
Ich habe versucht, dock->resize(m_compilerOutput->width(), m_compilerOutput->minimumHeight())
aufzurufen, m_compilerOutput->setSizePolicy()
mit jeder seiner Optionen aufzurufen ... Bisher hat sich nichts auf die Größe ausgewirkt. Wie ich bereits sagte, würde ich es vorziehen, eine einfache Lösung in ein paar Codezeilen zu erstellen, nur um sizeHint()
zu ändern. Alle Vorschläge werden geschätzt.
Ich habe gerade denselben Prozess durchlaufen. Nachdem ich viel zu viele Permutationen von resize()
, adjustSize()
und Freunden auf Dock-Widgets und deren enthaltenen Widgets ausprobiert hatte, funktionierte keines davon. Am Ende habe ich QListView
in Unterklassen unterteilt und diese sizeHint()
-Methode hinzugefügt.
Jetzt funktioniert es wie ein Zauber.
Ich habe es einfach gemacht: HEADER:
private void setDockSize(QDockWidget *dock, int, int);
public slots:
void returnToOldMaxMinSizes();
QUELLE:
QSize oldMaxSize, oldMinSize;
void MainWindow::setDockSize(QDockWidget* dock, int setWidth,int setHeight)
{
oldMaxSize=dock->maximumSize();
oldMinSize=dock->minimumSize();
if (setWidth>=0)
if (dock->width()<setWidth)
dock->setMinimumWidth(setWidth);
else dock->setMaximumWidth(setWidth);
if (setHeight>=0)
if (dock->height()<setHeight)
dock->setMinimumHeight(setHeight);
else dock->setMaximumHeight(setHeight);
QTimer::singleShot(1, this, SLOT(returnToOldMaxMinSizes()));
}
void MainWindow::returnToOldMaxMinSizes()
{
ui->dockWidget->setMinimumSize(oldMinSize);
ui->dockWidget->setMaximumSize(oldMaxSize);
}
Es hört sich so an, als würde sich das Dock-Widget in Anbetracht seines untergeordneten Widgets auf die richtige Größe verkleinern. Aus der QDockWidget-Dokumentation (Hervorhebung meiner):
Ein QDockWidget fungiert als Wrapper für sein untergeordnetes Widget, das mit setWidget () festgelegt wurde. Benutzerdefinierte Größenhinweise, minimale und maximale Größen und Größenrichtlinien sollten im untergeordneten Widget implementiert werden . QDockWidget respektiert sie und passt seine eigenen Einschränkungen an, um den Rahmen und den Titel einzuschließen. Größenbeschränkungen sollten nicht für das QDockWidget selbst festgelegt werden, da sie sich in Abhängigkeit davon ändern, ob es angedockt ist. Ein angedocktes QDockWidget hat keinen Rahmen und eine kleinere Titelleiste.
Um die Größe zu ändern, müssen Sie die Größe des untergeordneten Widgets ändern.
BEARBEITEN: Die Qt-Dokumentation kann manchmal irreführend sein, wenn es um Größenhinweise geht. Häufig bezieht es sich auf jede Art von Größenänderung, unabhängig davon, ob sie automatisch vom Widget oder programmgesteuert durchgeführt wird.
Dies ist eine alte Frage, aber ich wollte darauf hinweisen, dass Qt 5.6 die Funktion QMainWindow :: resizeDocks eingeführt hat, um dies zu handhaben.
Leider funktioniert es nicht für meinen Anwendungsfall (Verschieben des Trennzeichens zwischen zwei QDockWidgets, die mit QMainWindows :: splitDockWidget aufgeteilt wurden)
Sie könnten dies tun:
Legen Sie eine maximale Höhe für Ihre QTextEdit
fest:
m_compilerOutput = new QTextEdit;
m_compilerOutput->setMaximumHeight(100);
Und dann setzen Sie es im show event Ihres Hauptfensters wieder auf die alte Größe oder etwas Hoches:
void MainWindow::showEvent(QShowEvent *)
{
m_compilerOutput->setMaximumHeight(10000);
}
Das ist alles was Sie brauchen sollten.
Haben Sie versucht, resize()
für die QTextEdit
in Ihrem Dock-Widget aufzurufen? Sie können auch versuchen, die maximale und minimale Größe des Dock-Widgets vorübergehend auf die gewünschte Größe einzustellen und dann die ursprünglichen Werte wiederherzustellen.
Wenn die dockWidgets angedockt sind, werden die Größen von ihrem übergeordneten Element gesteuert. In solchen Fällen können Sie die Funktion QMainWindow::resizeDocks
verwenden.
Wenn schwebend, werden die Größen von ihren Kindern bestimmt. Ändern Sie die Größe der Kinder , um Ihren Zweck zu erreichen.
Tests mit Größenänderung für QDockWidget::widget()
(d. H. Das Widget, das von QDockWidget
verwaltet wird) funktionieren nicht wie erwartet.
Bei einer Unterklasse QDockWidget
(DW), in der bei einer Unterklasse QWidget
mit einem QHBoxLayout
zwei Widgets ( linkes Bedienfeld und rechtes Bedienfeld ) hinzugefügt wurden, deren Größenrichtlinien normalerweise auf QSizePolicy::Minimum
festgelegt wurden, hat die DW beide Panel Widgets sichtbar. Wenn sich der DW in einem seitlichen Dock befindet, verbirgt ein Anwendungs-Slot (QMainWindow
), der das Signal dockLocationChanged
des DW verarbeitet, das linke Bedienfeld und ändert die Größe von DW->widget()
auf die Größe des rechten Bedienfelds. Wenn der DW programmgesteuert in den unteren Dock-Bereich verschoben wird, wird leftPanel sichtbar und der DW füllt (natürlich) die gesamte Breite des Hauptfensters aus. Wenn der DW dann programmgesteuert in einen seitlichen Andockbereich verschoben wird, wird das linke Bedienfeld ausgeblendet und die Größe des DW verringert. Das funktioniert wie vorgesehen. Wenn der DW jedoch aus dem unteren Andockbereich in einen seitlichen Andockbereich gezogen wird, wird die Größe des DW nicht verringert, obwohl das linke Bedienfeld ausgeblendet ist und die Größenänderung wie zuvor angewendet wurde, wenn die Neupositionierung programmgesteuert durchgeführt wird. Sie können die Größe der DW manuell anpassen, indem Sie den Splitter-Handle zwischen der DW und dem zentralen Bereich des Hauptfensters ziehen. Beachten Sie, dass der zentrale Bereich des Hauptfensters ein QWidget
mit einem QHBoxLayout
mit Größenrichtlinien QSizePolicy::Expanding
ist.
Das Aufrufen von adjustSize
im Hauptfenster, nachdem die Größe des DW geändert wurde, hat keine Auswirkung. Dies, obwohl der DW sizeHint
neu implementiert hat, um seine Mindestgröße zurückzugeben, abhängig davon, ob das linke Bedienfeld sichtbar ist oder nicht.
Entweder fehlt mir etwas, um die Größe von QDockWidget
zu steuern (was angesichts der Schwierigkeiten, die ich beim Verstehen aller Interaktionen zwischen den Teilen des Layoutverwaltungssystems hatte, sehr wahrscheinlich ist), oder QMainWindow
ignoriert das Layout oder überschreibt es Anweisungen, die es gegeben wird. Eine genaue Untersuchung des Ereignisstroms während der Neupositionierungsvorgänge von QDockWidget
deutet auf Folgendes hin: Nachdem die Größenänderung des Signals dockLocationChanged
abgeschlossen und in die Ereignisschleife zurückgekehrt ist, kann ich feststellen, dass QMainWindow
beim Neupositionieren des Benutzers eine zusätzliche Größenänderung vornimmt Operationen auf dem betroffenen QDockWidget
machen somit die Anwendungslogik rückgängig, die versucht, die Dockgröße zu steuern. Irgendetwas scheint im QMainWindow
nicht zu stimmen ....
Das Problem beim Ändern der Größe von Dock-Widgets bei maximiertem MainWindow wird in QTBUG-16252 ( https://bugreports.qt.io/browse/QTBUG-16252 ) beschrieben.
Ich habe eine andere Problemumgehung gefunden. Funktioniert bei mir unter QT 5.4.1 minGW unter Windows7. Es sieht so aus, als ob einige Widget-Statuswiederherstellungsvorgänge eng mit der QApplication-Ereignisschleife zusammenhängen.
DockWidget-Größen werden NUR dann korrekt wiederhergestellt, wenn folgende Bedingungen erfüllt sind:
restoreGeometry () wird aufgerufen, BEVOR QApplication :: exec () eingegeben wird (z. B. im Konstruktor Ihrer MainWindow-Klasse).
restoreState () heißt AFTER exec () (z. B. über QTimer)
Hier ist mein Code:
int main(int argc, char *argv[])
{
QApplication application(argc, argv);
//...
MainWindow mainWindow;
mainWindow.show();
return application.exec();
}
MainWindow::MainWindow(...)
{
ui->setupUi(this);
//...
QTimer* nt = new QTimer(this);
nt->setSingleShot(true);
nt->setInterval( 100 );
connect(nt, SIGNAL(timeout()), SLOT(restoreWidgetSettings()));
nt->connect(nt, SIGNAL(timeout()), SLOT(deleteLater()));
nt->start();
restoreWidgetSettings(true);
}
void MainWindow::restoreWidgetSettings(bool geometryOnly) {
//...
QByteArray geometry = getSettings();
restoreGeometry(geometry);
if(geometryOnly)
return;
//... //create dock widgets here
restoreState(mainWindowState);
}