如何确定 QTableWidget 的正确大小?

新手上路,请多包涵

没有 办法设置 QTableWidget 的“正确”大小? (我是新手)这个测试代码只有 25 行长,在两个文件中,文件 Test.h:

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

和文件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();
}

然后是命令:

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

给出窗口:

不需要的窗口

但我们想要的当然更像是:

通缉窗口

Using tbl->width() seems to be useless, as it gives a default of 640 before test.show() , and the unwanted value of 195 after.我已经查看了 Qt Size Hints and Policies 直到我头晕目眩,并且我尝试 setResizeMode(QHeaderView::Fixed)setStretchLastSection(false) 。也许我错过了一些明显的东西?这是 CentOS 5 上的 Qt 4.7.4,如果这很重要的话。感谢您的任何帮助。

编辑:响应 DK, 如果 resize(1, 1); 行不存在,则存在 相同相反 的问题:窗口太大。

作为对多诺塔洛的回应,他补充说:

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

将给出所需的窗口大小(至少在我的机器上),但 不是 以所需的方式。我们应该如何计算“常数” 22288?

以及 Ton 对 Qt 的回答:如何强制隐藏的小部件计算其布局? 在这里似乎不起作用:添加 tbl->setAttribute(Qt::WA_DontShowOnScreen); tbl->show(); 使 tbl->width() 的值保持不变,为 640。

原文由 Joseph Quinsey 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 659
2 个回答

线程 如何设置 QTableWidget 的精确大小以防止出现滚动条? (Qt-interest 档案,2007 年 6 月) Lingfa Yang 和 Susan Macchia 之间似乎解决了我的问题。如果我的测试有效,我将很快发布更多详细信息。

更新#1 :我的测试现在生成漂亮的窗口:

成功的测试窗口

未更改 Test.h 的完整测试代码是:

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

一些注意事项:

  • 上述线程包含 verticalScrollBar()->width() 似乎是错误的。而且,在我的测试中,这始终是默认值 100 或值 15(如果已显示滚动条)。

  • 在此测试中,仅将 show(); hide(); 序列应用于 QTableWidget 不足以强制 Qt 重新计算几何图形。我需要将它应用到整个窗口。

  • 任何改进建议都会受到欢迎。 (我会在接受我自己的答案之前稍等片刻,以防有更好的解决方案。)

更新#2

  • 关于如何计算大小的详细信息,Qt-interest 线程可能是错误的(或者,至少,它与 运行 我的 机器的 Qt 版本不一致):每个网格线的 +1 是不必要的,但总体上需要 +4 .

  • 我仍在处理 layout()->invalidate() 与例如 QT: How to preview widgets in layout BEFORE a show() 的大小

更新#3

  • 这是我的最终版本——但我对它不是很满意。任何改进都会 非常 受欢迎。

  • 诸如 adjustSize()layout()->invalidate()Qt::WA_DontShowOnScreen 之类的东西似乎没有帮助。

  • 博客将 Qt 小部件缩小到所需的最小尺寸 很有趣,但使用 setSizeConstraint() 也一样好。

  • 后续修改表格需要用到 setSizeConstraint()move() 方法,这里没有展示。

  • 我的测试中有一件奇怪的事情,在 CentOS 5 上使用 Qt 4.6.3 和 4.7.4 完成。对于 hide(); show(); 序列,窗口位置被保存/恢复。但是大约 25% 的时间(图案不规则)恢复的位置在屏幕上会 _高出 24 个像素_,大概是窗口标题的高度。大约 10% 的时间 pos() 返回的值为 nullQt 网站 说对于 X11,它需要 nifty heuristics and clever code 为此,但某些地方似乎有问题。

原文由 Joseph Quinsey 发布,翻译遵循 CC BY-SA 3.0 许可协议

这不是标题中所述问题的答案,但我认为是对潜在问题的巧妙回答。

为了以完整尺寸显示 QTableWidget ,没有滚动条,您必须将其 sizeAdjustPolicy 设置为 QAbstractScrollArea::AdjustToContents (我假设为 QAbstractScrollArea::AdjustToContentsOnFirstShow 也可以)。

此外,您可能希望禁用该小部件的滚动条(为垂直和水平滚动条设置其滚动条策略),否则在显示滚动条时分配的小部件周围会有额外的空间。

参考:

原文由 Raven 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题