Wie bestimme ich die richtige Größe eines QTableWidget?

Lesezeit: 12 Minuten

Wie bestimme ich die richtige Grose eines QTableWidget
Joseph Quinsey

Gibt es beliebig Möglichkeit, die “richtige” Größe eines QTableWidget festzulegen? (Ich bin ein Neuling) Dieser Testcode ist nur 25 Zeilen lang, in zwei Dateien, mit der Datei Test.h:

#include <QtGui>
class Test : public QMainWindow {
   Q_OBJECT
public:
   Test();
};

und die Datei Test.cpp:

#include "Test.h"
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);
   QWidget *w = new QWidget;
   setCentralWidget(w);
   w->setLayout(vbox);
   resize(1, 1);
}

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

Dann der Befehl:

   qmake -project && qmake && make && ./Test

gibt das Fenster:

Unerwünschtes Fenster

Aber was wir wollen, ist natürlich eher:

Gesuchtes Fenster

Verwenden von tbl->width() scheint nutzlos zu sein, da es einen Standardwert von gibt 640 Vor test.show(), und der unerwünschte Wert von 195 nach. Ich habe mir die Qt-Size-Hinweise und -Richtlinien angesehen, bis sich mein Kopf drehte, und ich habe es versucht setResizeMode(QHeaderView::Fixed) und setStretchLastSection(false). Vielleicht übersehe ich etwas Offensichtliches? Dies ist mit Qt 4.7.4 auf CentOS 5, falls dies von Bedeutung ist. Vielen Dank für jede Hilfe.

Bearbeiten: Als Antwort auf DK, wenn die Linie resize(1, 1); ist nicht vorhanden, da ist die gleich und Gegenteil Problem: Das Fenster ist zu groß.

Und als Antwort auf Donotalo fügte er hinzu:

tbl->setMaximumWidth(222);
tbl->setMinimumWidth(222);
tbl->setMaximumHeight(88);
tbl->setMinimumHeight(88); 

ergibt die gewünschte Fenstergröße (zumindest auf meinem Computer), aber nicht auf die gewünschte Weise. Wie sollen wir die ‘Konstanten’ berechnen? 222 und 88?

Und Tons Antwort auf Qt: Wie kann man ein verstecktes Widget zwingen, sein Layout zu berechnen? scheint hier nicht zu funktionieren: das Hinzufügen von tbl->setAttribute(Qt::WA_DontShowOnScreen); tbl->show(); ließ den Wert von tbl->width() unverändert bei 640.

  • Ich habe das Gefühl, es ist einfach so resize(1, 1);.

    – DK

    7. Januar ’12 bei 1:53

  • Vielleicht möchten Sie es versuchen QWidget::setMinimumSize() auf Ihre Wunschgröße.

    – Donotalo

    7. Januar ’12 bei 3:22

  • Verwandte: Wie ändere ich die Größe von QTableView, damit der Bereich nicht mehr gescrollt wird?

    – Joseph Quinsey

    24. November ’18 um 17:20

Wie bestimme ich die richtige Grose eines QTableWidget
Joseph Quinsey

Der Faden Wie stelle ich eine genaue Größe von QTableWidget ein, um zu verhindern, dass Bildlaufleisten verwendet werden? (Qt-Interest-Archiv, Juni 2007) zwischen Lingfa Yang und Susan Macchia scheint meine Frage zu lösen. Ich werde in Kürze mehr Details posten, wenn meine Tests funktionieren.

Update #1: Mein Test generiert jetzt das hübsche Fenster:

erfolgreiches Testfenster

Der vollständige Testcode dafür, mit unverändertem Test.h, lautet:

#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();
}

Einige Notizen:

  • Die Aufnahme von . im obigen Thread verticalScrollBar()->width() scheint falsch zu sein. Und in meinen Tests war dies immer entweder ein Standardwert von 100 oder der Wert 15, wenn die Bildlaufleiste angezeigt wurde.

  • Anwenden der show(); hide(); Sequenz nur zum QTableWidget reichte in diesem Test nicht aus, um Qt zu zwingen, die Geometrie neu zu berechnen. Ich musste es auf das gesamte Fenster anwenden.

  • Verbesserungsvorschläge wären willkommen. (Ich werde etwas warten, bevor ich meine eigene Antwort akzeptiere, falls es bessere Lösungen gibt.)

Update #2:

  • Der Qt-Interest-Thread kann falsch sein (oder zumindest nicht übereinstimmen) mein Version von Qt läuft mein Maschine) bezüglich Details zur Berechnung der Größe: Das +1 für jede Rasterlinie ist nicht erforderlich, aber insgesamt ist +4 erforderlich.

  • ich arbeite noch durch layout()->invalidate() vs. zB QT: Vorschau der Größe von Widgets im Layout VOR eine Show().

Update #3:

  • Dies ist meine letzte Version – aber ich bin nicht sehr glücklich damit. Irgendwelche Verbesserungen wären sehr willkommen.

  • Dinge wie adjustSize() und layout()->invalidate() und Qt::WA_DontShowOnScreen scheinen nicht zu helfen.

  • Der Blog Qt-Widgets auf die erforderliche Mindestgröße verkleinern ist interessant, aber mit setSizeConstraint() ist genauso gut.

  • Der setSizeConstraint() und move() Methoden werden für spätere Änderungen an der Tabelle benötigt, die hier nicht gezeigt werden.

  • Bei meinen Tests auf CentOS 5 mit Qt 4.6.3 und 4.7.4 gab es etwas Seltsames. Für die hide(); show(); Sequenz wird die Fensterposition gespeichert/wiederhergestellt. Aber in etwa 25 % der Fälle (die Musterung war unregelmäßig) war die wiederhergestellte Position 24 Pixel höher auf dem Bildschirm, vermutlich die Höhe des Fenstertitels. Und in etwa 10 % der Fälle wird der Wert von . zurückgegeben pos() wäre Null. Der Qt-Site sagt für X11 braucht es nifty heuristics and clever code dafür, aber irgendwo scheint etwas kaputt zu sein.

  • Der von Ihnen erstellte Thread ist unter derselben URL nicht mehr verfügbar. 🙁 hmmmm… das kann es sein: archivum.info/qt-interest@trolltech.com/2007-06/00512/…

    – Jason S

    2. Januar ’14 um 16:01


  • @JasonS: Danke. Dieser Link sieht richtig aus. Ich werde meinen Beitrag bald aktualisieren.

    – Joseph Quinsey

    2. Januar ’14 um 16:07

  • Ich denke, du solltest verwenden t->frameWidth()*2 statt 4

    – Simon

    20. Juni ’14 um 19:30

  • Dieser Code funktioniert teilweise für mich. In meinem Fall sind meine vertikalen Überschriften länger als “1” oder “zwei”. Meine vertikalen Überschriften sind Zeichenfolgen von 15 oder 20 Zeichen. Um Bildlaufleisten zu vermeiden, muss ich den sizeHint der Kopfzeilen verwenden, um die richtige Größe des Tabellen-Widgets zu erhalten: int w = t->verticalHeader()->sizeHint().width() + 2; und: int h = t->horizontalHeader()->sizeHint().height() + 2; Das Hinzufügen von 4 zur Breite und Höhe ist zu viel: Ich muss nur 2 hinzufügen. Vielleicht enthält der sizeHint der Kopfzeilen keine Gitterlinie. Wenn Sie 1 hinzufügen, erscheinen die Bildlaufleisten.

    – pamplemousse_mk2

    9. September ’14 um 13:46


  • @JosephQuinsey: Ich bin aus der fernen Zukunft zurück ins Jahr 2012 gereist, um Ihre Antwort zur QTableWidget-Größe zu finden, wofür ich Ihnen immens danke! (Außerdem: Layouts in Qt lassen mich manchmal nach WPF suchen.)

    – Überdenken

    28. Februar ’18 um 12:20


1641784826 666 Wie bestimme ich die richtige Grose eines QTableWidget
Benutzer6419667

Hier ist meine (pythonische) Lösung für dieses Problem:

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())

Dies gibt mir eine Tabelle mit einer Größe, die alle Zeilen und Spalten perfekt umschließt.

  • Sollten Sie nicht die FrameWidth oder Ränder berücksichtigen?

    – Alexis

    8. Feb. 17 um 15:56 Uhr

  • Hat bei mir mit Ruby’s perfekt geklappt qtbindings auf Qt 4.8.6, außer dass ich +2 zur vertikalen festen Größe hinzugefügt habe, weil es ein wenig scrollen wollte, wenn ich es nicht tat.

    – Jason

    27. Juni ’17 um 18:21

Ich hatte das gleiche Problem und habe frühere Antworten optimiert, um einen korrekten Arbeitscode zu erhalten.

Zuerst erhalten wir Inhaltsränder von QTableWidget. Wenn Sie nur die Breite anpassen möchten, müssen Sie nur die horizontale Bildlaufleiste deaktivieren.:

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();

Dann hängen wir die Breite der vertikalen Kopfzeile an an w. Die vertikale Kopfzeile ist eine spezielle Spalte, die Zeilenindizes enthält und standardmäßig aktiviert ist. Wir fügen auch die Höhe des horizontalen Headers an . an h. Die horizontale Kopfzeile ist eine spezielle Zeile, die Spaltentitel enthält.

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

Dann hängen wir die Breite jeder Spalte an w, und Höhe jeder Reihe zu h.

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

Nun, wenn w oder h sind zu groß, um auf das Fenster zu passen, wir verkleinern sie, damit sie hineinpassen 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();

Eine bessere Bewerbung kenne ich leider nicht w und h um Breite und Höhe von . einzustellen QTableWidget. Wenn ich verwende:

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

Dann kann der Benutzer die Größe des Widgets überhaupt nicht ändern. Ich denke, wir müssen eine Art manuelles Layout verwenden.

Es mag etwas abseits vom Thema erscheinen, aber wenn Sie möchten, dass Ihre Tabelle eine ansprechendere Ansicht hat, verwenden Sie diesen Befehl, um die Spaltengröße an ihre Daten anzupassen:

ui->tableWidget->resizeColumnsToContents();

1641784826 394 Wie bestimme ich die richtige Grose eines QTableWidget
Celdor

Vor kurzem habe ich das gleiche Problem gefunden. Ich habe Dutzende von Funktionen getestet, die Google in Qt Center, Qt Project gefunden hat, aber keine davon hat mir die richtige Größe gegeben. Ich habe diese Funktion erstellt, von der ich glaube, dass sie die nächste Tabellengröße berechnet. Die Funktion bietet eine richtige vertikale, aber etwas größere horizontale Größe – es sieht so aus, als ob sie immer noch eine vertikale Bildlaufleiste abdeckt. Außerdem habe ich überprüft, ob die Tischabmessungen eine Desktop-Größe überschreiten:

const QRect MyApp::adjustTableSize(
    QTableView* tv,
    const QVBoxLayout* lay,
    const int& maxRows,
    const int& maxCols) {
// get Desktop size
using std::size_t;
QDesktopWidget desktop;
size_t desW = desktop.screen()->width();
size_t desH = desktop.screen()->height();

int leftM,rightM,topM,bottomM;
lay->getContentsMargins(&leftM,&topM,&rightM,&bottomM);

size_t extraTopHeight = topM + tv->frameWidth();
size_t extraBottomHeight = bottomM + tv->frameWidth();
size_t extraLeftWidth = leftM + tv->frameWidth();
size_t extraRightWidth = rightM + tv->frameWidth();
size_t w = tv->verticalHeader()->width() + extraLeftWidth + extraRightWidth;
size_t h = tv->horizontalHeader()->height() + extraTopHeight + extraBottomHeight;
for(size_t col = 0; col < maxCols; ++col) {
    w += tv->columnWidth(col);
}
for(size_t row = 0; row < maxRows; ++row ) {
    h += tv->rowHeight(row);
}

std::size_t x,y;
if((w - extraLeftWidth - extraRightWidth) > desW) {
    x = 0;
    w = desW - extraLeftWidth - extraRightWidth;
} else
    x = (desW - w)/2;
if(h - extraTopHeight - extraBottomHeight - QStyle::PM_TitleBarHeight > desH) {
    y = extraTopHeight + QStyle::PM_TitleBarHeight;
    h = desH - (extraTopHeight + QStyle::PM_TitleBarHeight + extraBottomHeight);
} else
    y = (desH - h)/2;
return QRect(x,y,w,h);
}

Ein paar Randnotizen:

QTableView.
Ich habe QTableView verwendet, aber ich denke, es kann auch mit QTableWidget funktionieren.

QVBoxLayout.
Ich bin mir ziemlich sicher, dass stattdessen jedes der in Qt verfügbaren Layouts in dieser Funktion verwendet werden kann.

Hoffe, diese Funktion kann jedem helfen.

1641784826 995 Wie bestimme ich die richtige Grose eines QTableWidget
Zbyněk Winkler

Um die Breite der Tabelle zu erhalten, addieren Sie die Breite der vertikalen und horizontalen Kopfzeilen und das Doppelte der Rahmenbreite. Das gleiche gilt für die Höhe:

w = verticalHeader()->width() + horizontalHeader()->length() + frameWidth()*2
h = horizontalHeader()->height() + verticalHeader()->length() + frameWidth()*2

Es gibt mehrere Möglichkeiten, sie je nach Ihren Umständen einzustellen. Am besten wäre es wahrscheinlich, sizeHint() zu überschreiben, um Ihre Werte zurückzugeben. Auf diese Weise bleibt der Tisch in der Größe veränderbar, aber ohne andere Anforderungen wird Ihre Größe sein.

Der Schlüssel, um dies zum Laufen zu bringen, ist die Verwendung der length() Methode an den richtigen Stellen statt nur width() oder height(). Ich weiß nicht genau warum, aber hier tut es das Richtige 😉

  • Diese Lösung funktionierte für mich, aber mit wenigen Anpassungen (Qt4.8): Ich musste verwenden length statt Breite/Höhe (überraschenderweise nicht dasselbe…). Si ich endete mit w = verticalHeader()->width() + horizontalHeader()->length() + frameWidth()*2 und h = horizontalHeader()->height() + verticalHeader()->length() + frameWidth()*2

    – Alexis

    8. Februar ’17 um 15:55

  • @Alexis du hast recht. Ich habe meinen aktuellen Code doppelt überprüft und verwende den gleichen. Ich werde meine Antworten als solche aktualisieren. Danke!

    – Zbyněk Winkler

    10. Februar ’17 um 9:52

1641784826 838 Wie bestimme ich die richtige Grose eines QTableWidget
Toby Speight

Ich kann den Beitrag von Joseph Qunesey / Celdor nicht kommentieren, also schreibe ich ihn hier rein: Um den wahren Wert von . abzurufen QStyle::PM_TitleBarHeight, sollten Sie wie folgt vorgehen:

QStyle *style;
if(tv->style())
{
    style = tv->style();
}
else
{
    style = QApplication::style();
}
int titleBarHeight = style->pixelMetric(QStyle::PM_TitleBarHeight));

Dies liegt daran, dass der Aufzählung keine genauen Werte zugewiesen sind. Ich denke, Ihr Missverständnis darüber, wie es funktioniert, lag an der irreführenden Qt Dokumentation wobei es so aussieht, als ob die Aufzählung die Werte direkt repräsentiert, während dies natürlich nicht der Fall ist (da es stilabhängig ist).

  • Diese Lösung funktionierte für mich, aber mit wenigen Anpassungen (Qt4.8): Ich musste verwenden length statt Breite/Höhe (überraschenderweise nicht dasselbe…). Si ich endete mit w = verticalHeader()->width() + horizontalHeader()->length() + frameWidth()*2 und h = horizontalHeader()->height() + verticalHeader()->length() + frameWidth()*2

    – Alexis

    8. Februar ’17 um 15:55

  • @Alexis du hast recht. Ich habe meinen aktuellen Code doppelt überprüft und verwende den gleichen. Ich werde meine Antworten als solche aktualisieren. Danke!

    – Zbyněk Winkler

    10. Februar ’17 um 9:52

Wie bestimme ich die richtige Grose eines QTableWidget
Rabe

Dies ist keine Antwort auf die im Titel genannte Frage, aber ich denke, eine saubere Antwort auf das zugrunde liegende Problem.

Um ein anzuzeigen QTableWidget in voller Größe, ohne Scrollbars, müssen Sie es einstellen sizeAdjustPolicy zu QAbstractScrollArea::AdjustToContents (Ich nehme an QAbstractScrollArea::AdjustToContentsOnFirstShow würde auch funktionieren).

Außerdem möchten Sie möglicherweise die Bildlaufleisten für dieses Widget deaktivieren (wobei die Bildlaufleisten-Richtlinien für vertikale und horizontale Bildlaufleisten festgelegt werden), da sonst um das Widget herum zusätzlicher Platz für die Anzeige von Bildlaufleisten bereitgestellt wird.

Referenzen:

.

266790cookie-checkWie bestimme ich die richtige Größe eines QTableWidget?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy