Saltar al contenido

¿Cómo determinar el tamaño correcto de un QTableWidget?

Estate atento ya que en esta reseña vas a hallar la respuesta que buscas.

Solución:

El hilo ¿Cómo establecer un tamaño preciso de QTableWidget para evitar tener barras de desplazamiento? (Archivo Qt-interest, junio de 2007) entre Lingfa Yang y Susan Macchia parece resolver mi duda. Publicaré más detalles en breve, si mis pruebas funcionan.

Actualización #1: Mi prueba ahora genera la ventana de aspecto agradable:

ventana de prueba exitosa

El código de prueba completo para esto, con Test.h sin cambios, es:

#include "Test.h"

static QSize myGetQTableWidgetSize(QTableWidget *t) 
   int w = t->verticalHeader()->width() + 4; // +4 seems to be needed
   for (int i = 0; i < t->columnCount(); i++)
      w += t->columnWidth(i); // seems to include gridline (on my machine)
   int h = t->horizontalHeader()->height() + 4;
   for (int i = 0; i < t->rowCount(); i++)
      h += t->rowHeight(i);
   return QSize(w, h);


static void myRedoGeometry(QWidget *w) 
   const bool vis = w->isVisible();
   const QPoint pos = w->pos();
   w->hide();
   w->show();
   w->setVisible(vis);
   if (vis && !pos.isNull())
      w->move(pos);


Test::Test() : QMainWindow() 
   QVBoxLayout *vbox = new QVBoxLayout;
   QPushButton *btn  = new QPushButton("Hello World etc etc etc etc etc");
   QTableWidget *tbl = new QTableWidget(2, 2);
   vbox->addWidget(btn);
   vbox->addWidget(tbl);
   setCentralWidget(new QWidget);
   centralWidget()->setLayout(vbox);
   layout()->setSizeConstraint(QLayout::SetMinimumSize); // or SetFixedSize

   tbl->setVerticalHeaderItem(1, new QTableWidgetItem("two")); // change size
   myRedoGeometry(this);
   tbl->setMaximumSize(myGetQTableWidgetSize(tbl));
   tbl->setMinimumSize(tbl->maximumSize()); // optional


int main(int argc, char *argv[]) 
   QApplication app(argc, argv);
   Test test;
   test.show();
   app.exec();

Algunas notas:

  • La inclusión del hilo anterior de verticalScrollBar()->width() parece estar mal Y, en mis pruebas, siempre fue un valor predeterminado de 100 o el valor 15, si se había mostrado la barra de desplazamiento.

  • Aplicando el show(); hide(); La secuencia solo para QTableWidget no fue suficiente para forzar a Qt a recalcular la geometría, en esta prueba. Necesitaba aplicarlo a toda la ventana.

  • Cualquier sugerencia de mejora sería bienvenida. (Esperaré un poco antes de aceptar mi propia respuesta, en caso de que haya mejores soluciones).

Actualización #2:

  • El hilo de Qt-interest puede estar equivocado (o, al menos, no está de acuerdo con mi versión de Qt en ejecución mi máquina) con respecto a los detalles sobre cómo calcular el tamaño: el +1 para cada línea de cuadrícula es innecesario, pero se necesita un +4 general.

  • todavía estoy trabajando layout()->invalidate() vs. por ejemplo, QT: cómo obtener una vista previa de los tamaños de los widgets en el diseño ANTES DE un espectáculo().

Actualización #3:

  • Esta es mi versión final, pero no estoy muy contento con ella. Cualquier mejora sería muy bienvenidos.

  • Cosas como adjustSize() y layout()->invalidate() y Qt::WA_DontShowOnScreen no parece ayudar.

  • El blog Reducir los widgets de Qt al tamaño mínimo necesario es interesante, pero usar setSizeConstraint() es igual de bueno.

  • los setSizeConstraint() y move() se necesitan métodos para cambios posteriores en la tabla, que no se muestran aquí.

  • Hubo algo extraño en mi prueba, realizada en CentOS 5 con Qt 4.6.3 y 4.7.4. Para el hide(); show(); secuencia, la posición de la ventana se guarda/restaura. Pero alrededor del 25% de las veces (el patrón era irregular) la posición restaurada sería 24 píxeles más alto en la pantalla, presumiblemente la altura del título de la ventana. Y alrededor del 10% de las veces el valor devuelto por pos() sería null. El sitio Qt dice que para X11 necesita nifty heuristics and clever code para esto, pero algo parece estar roto en alguna parte.

Aquí está mi solución (pitónica) a este problema:

table.setSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)

table.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff)
table.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff)

table.resizeColumnsToContents()
table.setFixedSize(table.horizontalHeader()->length() + 
                   table.verticalHeader()->width(),
                   table.verticalHeader()->length() + 
                   table.horizontalHeader()->height())

Esto me da una tabla con un tamaño que envuelve perfectamente todas las filas y columnas.

Estaba lidiando con el mismo problema y modifiqué las respuestas anteriores para obtener un código de trabajo correcto.

Primero, obtenemos márgenes de contenido de QTableWidget. Si solo desea ajustar su ancho, solo necesita deshabilitar la barra de desplazamiento horizontal:

int w = 0, h = 0;
ui->tableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->tableWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

w += ui->tableWidget->contentsMargins().left()
        + ui->tableWidget->contentsMargins().right();
h += ui->tableWidget->contentsMargins().top()
        + ui->tableWidget->contentsMargins().bottom();

Luego, agregamos el ancho del encabezado vertical a w. El encabezado vertical es una columna especial que contiene índices de filas y está habilitado de forma predeterminada. también añadimos la altura del encabezado horizontal a h. El encabezado horizontal es una fila especial que contiene títulos de columna.

w += ui->tableWidget->verticalHeader()->width();
h += ui->tableWidget->horizontalHeader()->height();

Luego, agregamos el ancho de cada columna a wy la altura de cada fila a h.

for (int i=0; itableWidget->columnCount(); ++i)
    w += ui->tableWidget->columnWidth(i);
for (int i=0; itableWidget->rowCount(); ++i)
    h += ui->tableWidget->rowHeight(i);

Ahora si w o h son demasiado grandes para caber en la ventana, los reducimos para que quepan ui->centralWidget->contentsRect().

if (w > ui->centralWidget->contentsRect().width())
    w = ui->centralWidget->contentsRect().width();
if (h > ui->centralWidget->contentsRect().height())
    h = ui->centralWidget->contentsRect().height();

Desafortunadamente, no conozco una mejor manera de aplicar w y h para establecer el ancho y la altura de QTableWidget. Si uso:

ui->tableWidget->setMinimumWidth(w);
ui->tableWidget->setMaximumWidth(w);
ui->tableWidget->setMinimumHeight(h);
ui->tableWidget->setMaximumHeight(h);

Entonces el usuario no podrá cambiar el tamaño del widget en absoluto. Creo que necesitamos usar algún tipo de diseño manual.

Puede parecer un poco fuera de tema, pero si desea que su tabla tenga una vista más atractiva, use este comando para cambiar el tamaño de las columnas para que se ajusten a sus datos:

ui->tableWidget->resizeColumnsToContents();

Eres capaz de apoyar nuestra función ejecutando un comentario y dejando una puntuación te damos la bienvenida.

¡Haz clic para puntuar esta entrada!
(Votos: 2 Promedio: 5)


Tags : / /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *