2
我正在實現drap-and-drop事件過濾器來重新排列布局中的小部件,並且一次將其中幾個彈出到隊列中,在拖動小部件所在的位置添加橡皮筋,然後添加小部件的其餘部分回佈局(因爲似乎沒有被使用QLayout接口「在插入」的方式)像這樣:任何方式來暫時停止佈局重新計算?
// HANDLE DRAG ENTER EVENTS
if (p_event->type() == QEvent::DragEnter)
{
QDragEnterEvent* dragEnterEvent = static_cast<QDragEnterEvent*>(p_event);
if (dragEnterEvent->mimeData()->hasFormat("text/plain"))
{
QString objectName = dragEnterEvent->mimeData()->text();
// findChild doesn't work on layouts because they don't ever
// inject themselves into the parent/child hierarchy, so we
// use the itemAt approach instead.
for (int i = 0; i < layout->count(); ++i)
{
dragItem = layout->itemAt(i)->widget();
if (dragItem->objectName() == objectName)
{
dragEnterEvent->acceptProposedAction();
// 'Rearrange' the widgets. This basically entails removing
// everything after the drag item, adding a placeh older, and
// then adding them back
QQueue<QWidget*> fifo;
// take everything after the drag item out
// important to have count as a local var, because otherwise it will
// decrement with every loop iteration.
int count = layout->count();
for (int j = i + 1; j < count; j++)
{
fifo.enqueue(layout->takeAt(i+1)->widget()); // the indices shift left on their own, so we only ever want to take i+1.
}
// add a 'rubber band' placeholder
m_band = new QRubberBand(QRubberBand::Rectangle);
m_band->setObjectName("placeholderBand");
m_band->setVisible(true);
m_band->setFixedSize(dragItem->size());
layout->addWidget(m_band);
// put the widgets in the fifo back in
count = fifo.count();
for(int j = 0; j < count; j++)
{
layout->addWidget(fifo.dequeue());
}
break;
}
}
}
}
這種方法的問題是加法/小部件的去除導致非常明顯和令人討厭的閃爍。是否有任何
- 一些方法可以讓我從重新計算本身直到所有的添加/刪除操作停止佈局完成後,或
- 一些更好的方式來插入部件到佈局(僅使用
QLayout
接口)那不會造成閃爍?
是的,你說得對,我看到更多的源和內addWidget只有 'addChildWidget(W);' '的addItem( QLayoutPrivate :: createWidgetItem(this,w));'並且沒有任何一種方法不會調用update或其他東西 – Chernobyl 2014-10-20 19:15:11