Возможным решением является повторное добавление виджетов, которые должны быть перемещены.Т.е.
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_;
};
И в источнике (показывая толькоконструктор, обработка фокуса и exec):
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();
Создает следующий виджет:
Комментарии и способы сделать это лучше, или почему это просто неправильно, приветствуются :))