(使用Qt 4.6.3,x64,linux)
我正在测试如何将小部件正确插入到充满各种小部件的现有QGridLayout
中。一个细分的设计案例如下:
QApplication app(argc,argv);
QWidget w;
QGridLayout* gl = new QGridLayout(&w);
QLabel* label = new QLabel("Image Size:");
QLineEdit* wedit = new QLineEdit("100");
QLabel* xlabel = new QLabel("x");
wedit->setAlignment(Qt::AlignRight);
gl->addWidget(label);
gl->addWidget(xlabel, 0, 1, 1, 1);
gl->addWidget(wedit, 0, gl->columnCount());
创建以下小部件:
假设上面有一个现有的QGridLayout,但没有“x”标签,并且我希望将其插入到布局中,切换后两个addWidget行可能看似有效,即:
\\ same as above
gl->addWidget(label);
gl->addWidget(wedit, 0, gl->columnCount());
gl->addWidget(xlabel, 0, 1, 1, 1);
然而,这会产生以下结果:
此后的gl->columnCount()
仍为2,因为x-label和QLineEdit都填充了同一个单元格。基于这些知识,以下代码产生了初始的期望结果:
gl->addWidget(label);
gl->addWidget(wedit, 0, 2); // note: specified column 2, columnCount() is now 3
gl->addWidget(xlabel, 0, 1, 1, 1);
虽然这不是特别有用,但因为有问题的原始布局并未考虑到以后的布局。
由于addWidget允许指定单元格位置以及行/列跨度,因此Qt不会自动替换布局中的现有小部件似乎很奇怪。有没有人建议如何克服这个问题?我假设可以重新创建一个QGridLayout并将其复制到原始子节点中,注意将其他小部件插入到正确的位置。然而,这很难看,并且易受Qt版本问题的影响(因为我想修改内置的小部件)。
修改:
我意识到我正在以QHBoxLayout
方式进行思考,其中插入小部件是唯一理解的,而在QGridLayout
中则不是这种情况(?)。< / p>
我可以通过在两个较低行(即“文件和名称:”上方)上方插入一个小部件(类似于上面显示的小部件)来澄清我最终想要修改QFileDialog::getSaveFileName
。 / p>
由于
答案 0 :(得分:1)
切换后两行addWidget
行无效。对于以下代码:
gl->addWidget(label);
gl->addWidget(wedit, 0, gl->columnCount());
gl->addWidget(xlabel, 0, 1, 1, 1);
在添加窗口小部件之前评估addWidget()
调用的参数。因此,gl->columnCount()
对第二次调用求值为1而不是2,因为仍然需要创建列。您实际上是在第一列添加了两个小部件。
答案 1 :(得分:0)
可能的解决方案是重新添加应重新定位的小部件。即
QLayoutItem* x01 = gl->itemAtPosition(0,1);
gl->addWidget(x01->widget(), 0, 2);
gl->addWidget(xlabel, 0, 1, 1, 1);
现在,这不是特别漂亮或易于维护,因为Qt的新版本可能会改变原始小部件,而盲目地挑选和重新安置儿童并不是那么聪明。以下真实示例(我实际想要解决的那个)是改变Qt的“另存为”对话框窗口,该窗口显示使用QFileDialog :: getSaveFileName。
class ImageFileDialog : public QFileDialog {
public:
ImageFileDialog(QWidget* parent);
~ImageFileDialog();
QString getFileName() const;
QSize getImageSize() const;
QDialog::DialogCode exec(); // Overriden
protected:
void showEvent(QShowEvent* event); // Overriden
private:
QString fileName_;
QSize imageSize_;
QLineEdit* widthLineEdit_;
QLineEdit* heightLineEdit_;
};
在源代码中(仅显示构造函数,焦点处理和执行):
ImageFileDialog::ImageFileDialog(QWidget* parent)
: fileName_(""),
imageSize_(0,0),
widthLineEdit_(0),
heightLineEdit_(0)
{
setAcceptMode(QFileDialog::AcceptSave);
setFileMode(QFileDialog::AnyFile);
setConfirmOverwrite(true);
QGridLayout* mainLayout = dynamic_cast<QGridLayout*>(layout());
assert(mainLayout->columnCount() == 3);
assert(mainLayout->rowCount() == 4);
QWidget* container = new QWidget();
QGridLayout* glayout = new QGridLayout();
QLabel* imageSizeLabel = new QLabel("Image Size:");
widthLineEdit_ = new QLineEdit("400");
heightLineEdit_ = new QLineEdit("300");
widthLineEdit_->setAlignment(Qt::AlignRight);
heightLineEdit_->setAlignment(Qt::AlignRight);
container->setLayout(glayout);
glayout->setAlignment(Qt::AlignLeft);
glayout->addWidget(widthLineEdit_);
glayout->addWidget(new QLabel("x"), 0, 1);
glayout->addWidget(heightLineEdit_, 0, 2);
glayout->addWidget(new QLabel("[pixels]"), 0, 3);
glayout->addItem(new QSpacerItem(250, 0), 0, 4);
glayout->setContentsMargins(0,0,0,0); // Removes unwanted spacing
// Shifting relevant child widgets one row down.
int rowCount = mainLayout->rowCount();
QLayoutItem* x00 = mainLayout->itemAtPosition(mainLayout->rowCount()-2,0);
QLayoutItem* x10 = mainLayout->itemAtPosition(mainLayout->rowCount()-1,0);
QLayoutItem* x01 = mainLayout->itemAtPosition(mainLayout->rowCount()-2,1);
QLayoutItem* x11 = mainLayout->itemAtPosition(mainLayout->rowCount()-1,1);
QLayoutItem* x02 = mainLayout->itemAtPosition(mainLayout->rowCount()-1,2);
assert(x00); assert(x01); assert(x10); assert(x11); assert(x02);
mainLayout->addWidget(x00->widget(), rowCount-1, 0, 1, 1);
mainLayout->addWidget(x10->widget(), rowCount, 0, 1, 1);
mainLayout->addWidget(x01->widget(), rowCount-1, 1, 1, 1);
mainLayout->addWidget(x11->widget(), rowCount, 1, 1, 1);
mainLayout->addWidget(x02->widget(), rowCount-1, 2, 2, 1);
// Adding the widgets in the now empty row.
rowCount = mainLayout->rowCount();
mainLayout->addWidget(imageSizeLabel, rowCount-3, 0, 1, 1 );
mainLayout->addWidget(container, rowCount-3, 1, 1, 1);
// Setting the proper tab-order
QLayoutItem* tmp = mainLayout->itemAtPosition(mainLayout->rowCount()-2,1);
QLayoutItem* tmp2 = mainLayout->itemAtPosition(mainLayout->rowCount()-1,1);
assert(tmp); assert(tmp2);
QWidget::setTabOrder(heightLineEdit_ , tmp->widget());
QWidget::setTabOrder(tmp->widget(), tmp2->widget());
}
// Makes sure the right widget is in focus
void ImageFileDialog::showEvent(QShowEvent* event)
{
widthLineEdit_->setFocus(Qt::OtherFocusReason);
}
// Called to create the widget
QDialog::DialogCode ImageFileDialog::exec()
{
if (QFileDialog::exec() == QDialog::Rejected)
return QDialog::Rejected;
// The code that processes the widget form and stores results for later calls to
// getImageSize()
return QDialog:Accepted;
}
其中,例如使用
ImageFileDialog* dialog = new ImageFileDialog(&w);
dialog->exec();
创建以下小部件:
非常欢迎评论和更好地做到这一点的方法,或者为什么这是完全错误的。)