¿C++ cambia el tamaño de Qt QDockWidget acoplado mediante programación?
resize (9)
¿Has intentado llamar a QTextEdit
resize()
en el QTextEdit
dentro de tu widget de dock? También podría intentar establecer temporalmente los tamaños máximos y mínimos del artilugio del muelle al tamaño que desea que sea, y restaurar los valores originales.
Empecé a trabajar en un nuevo proyecto de C ++ / Qt. Va a ser un IDE basado en MDI con widgets acoplados para cosas como el árbol de archivos, el buscador de objetos, el resultado del compilador, etc. Sin embargo, una cosa me está molestando hasta ahora: no puedo imaginar cómo hacer un QDockWidget
más pequeño en un QDockWidget
. Por ejemplo, este fragmento crea mi ventana de base, "Información de compilación":
m_compilerOutput = new QTextEdit;
m_compilerOutput->setReadOnly(true);
dock = new QDockWidget(tr("Build Information"), this);
dock->setWidget(m_compilerOutput);
addDockWidget(Qt::BottomDockWidgetArea, dock);
Cuando se lanzó, mi programa se ve así (tenga en cuenta la etapa inicial del desarrollo):
Sin embargo, quiero que aparezca así:
Parece que no puedo hacer que esto suceda. La referencia de Qt en QDockWidget dice esto:
Se deben implementar sugerencias de tamaño personalizado, tamaños mínimo y máximo y políticas de tamaño en el widget hijo. QDockWidget los respetará, ajustando sus propias restricciones para incluir el marco y el título. Las restricciones de tamaño no deberían establecerse en el QDockWidget en sí, ya que cambian según esté acoplado.
Ahora, esto sugiere que un método para hacer esto sería QTextEdit
y anular el método sizeHint()
. Sin embargo, preferiría no hacer esto solo para ese propósito, ni he intentado que sea una solución funcional.
He intentado llamar a dock->resize(m_compilerOutput->width(), m_compilerOutput->minimumHeight())
, llamando a m_compilerOutput->setSizePolicy()
con cada una de sus opciones ... Hasta el momento, nada ha afectado al tamaño. Como dije, preferiría una solución simple en algunas líneas de código para tener que crear una subclase solo para cambiar sizeHint()
. Todas las sugerencias son apreciadas.
Acabo de pasar por este mismo proceso. Después de probar demasiadas permutaciones de adjustSize()
resize()
, adjustSize()
y amigos en widgets de base y su widget contenido, ninguno de los cuales funcionó, terminé QListView
y agregando ese método sizeHint()
.
Ahora funciona como un encanto!
El problema de redimensionar los widgets cuando MainWindow está maximizado se describe en QTBUG-16252 ( https://bugreports.qt.io/browse/QTBUG-16252 )
He encontrado otra solución alternativa. Funciona para mí en QT 5.4.1 minGW en Windows7. Parece que algunas operaciones de restauración de estado de widgets están estrechamente relacionadas con el bucle de evento QApplication.
Los tamaños de DockWidget se restauran correctamente SÓLO cuando se cumplen las siguientes condiciones:
restoreGeometry () se llama ANTES de ingresar QApplication :: exec () (por ejemplo, en el constructor de su clase MainWindow)
restoreState () se llama AFTER exec () (por ejemplo, a través de QTimer)
Aquí está mi código:
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);
}
Esta es una vieja pregunta, pero quería mencionar que Qt 5.6 introdujo la función QMainWindow::resizeDocks para manejar esto.
Desafortunadamente, no funciona para mi caso de uso (separador móvil entre dos QDockWidgets que se han dividido con QMainWindows :: splitDockWidget)
Las pruebas que utilizan el tamaño en el QDockWidget::widget()
(es decir, el widget que el QDockWidget
está administrando) no funcionan de manera consistente como se esperaba.
Con una subclase QDockWidget
(DW) en la que se QWidget
un QWidget
con QHBoxLayout
que tiene dos widgets ( panel izquierdo y panel derecho ), todos los cuales tienen sus políticas de tamaño establecidas en QSizePolicy::Minimum
, el DW normalmente tiene ambos paneles widgets visibles. Cuando el DW se coloca en un dock lateral, una ranura de aplicación ( QMainWindow
) que maneja la señal dockLocationChanged
del DW oculta el panel izquierdo y vuelve a dimensionar el DW->widget()
en el panel derecho del tamaño. Cuando el DW se mueve programáticamente al área inferior del muelle LeftPanel se configura como visible y el DW ocupa todo el ancho de la ventana principal (por supuesto). Cuando el DW se mueve programáticamente a un área de la plataforma lateral, el panel izquierdo se oculta y el DW se vuelve a dimensionar. Esto funciona según lo previsto. Sin embargo, si el DW se arrastra desde el área de la base inferior a un área lateral, aunque el panel izquierdo esté oculto y se vuelva a aplicar el tamaño como antes, el DW no se vuelve a dimensionar como cuando el reposicionamiento se realiza programáticamente. El DW se puede cambiar de tamaño manualmente arrastrando la palanca de separación entre el DW y el área central de la ventana principal. Tenga en cuenta que el área central de la ventana principal es un QWidget
tiene un QHBoxLayout
con políticas de tamaño QSizePolicy::Expanding
.
Llamar a adjustSize
en la ventana principal después de que se haya redimensionado el DW no tiene ningún efecto. Esto a pesar de que DW ha sizeHint
a sizeHint
para devolver su tamaño mínimo dependiendo de si el panel izquierdo es visible o no.
O me falta algo sobre cómo controlar el tamaño de QDockWidget
(que, dada la dificultad que he tenido para entender todas las interacciones entre las partes del sistema de administración de diseño, es bastante probable), o QMainWindow
está ignorando o anulando el diseño instrucciones que se le están dando. Al examinar de cerca la secuencia de eventos durante las operaciones de reposicionamiento de QDockWidget
: Después de que el manejo de la ranura dockLocationChanged
haya realizado su redimensionamiento y haya regresado al ciclo de eventos, puedo ver que QMainWindow
, cuando el reposicionamiento del usuario finaliza, aplica un tamaño adicional operaciones en el QDockWidget
afectado, lo que deshace la lógica de la aplicación que intenta controlar el tamaño del puerto. Algo parece estar mal en QMainWindow
....
Lo hice fácil: HEADER:
private void setDockSize(QDockWidget *dock, int, int);
public slots:
void returnToOldMaxMinSizes();
FUENTE:
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);
}
Parece que el widget del puerto se reajusta al tamaño adecuado, teniendo en cuenta su widget hijo. De la documentación QDockWidget (énfasis mío):
Un QDockWidget actúa como un contenedor para su widget hijo, configurado con setWidget (). Se deben implementar sugerencias de tamaño personalizado, tamaños mínimo y máximo y políticas de tamaño en el widget hijo . QDockWidget los respetará, ajustando sus propias restricciones para incluir el marco y el título. Las restricciones de tamaño no deberían establecerse en el QDockWidget en sí, ya que cambian dependiendo de si están acopladas; un QDockWidget acoplado no tiene marco y una barra de título más pequeña.
Para cambiar el tamaño, debe cambiar el tamaño del widget secundario.
EDITAR: la documentación de Qt a veces puede ser engañosa cuando se discuten sugerencias de tamaño. A menudo, se refiere a cualquier tipo de cambio de tamaño, ya sea realizado automáticamente por el widget o programáticamente.
Podrías hacer esto:
Establezca una altura máxima para su QTextEdit
:
m_compilerOutput = new QTextEdit;
m_compilerOutput->setMaximumHeight(100);
Y luego, en el evento show de su ventana principal, vuelva a configurar el tamaño anterior o algo alto:
void MainWindow::showEvent(QShowEvent *)
{
m_compilerOutput->setMaximumHeight(10000);
}
Eso es todo lo que deberías necesitar.
Si los dockWidgets están acoplados, los tamaños son controlados por sus padres. En tales casos, puede usar la función QMainWindow::resizeDocks
.
Si flota, los tamaños son determinados por sus hijos. Cambiar el tamaño de los niños para lograr su propósito.