Bug #926
closedWBoxLayout : insert and remove operations are very very very slow
0%
Description
Hi guys ,
Since I have upgraded to 3.9.10 my operations related to WVBoxLayout , WHBoxLayout , WBoxLayout are very very very very slow
it took about 10 seconds to remove and reinsert a simple widget into a WVBoxLayout with only 25 items .....
Could you take a look at this mysterious slow-down ?
Best regards.
Mohamed
Files
Updated by Momo LALMI over 13 years ago
This seems to happen only with Google chrome (latest version).
When reordering layout items using insertItem , removeItem , all layout elements became invisible for some seconds and sometimes do not reappear at all (until the mouse is moved over)
Updated by Koen Deforche over 13 years ago
Hey Mohammed,
Unfortunately, with Chrome's self-update mechanism it will not be easy to reproduce this... But still, would you be able to provide a test case that triggers this for you?
Regards,
koen
Updated by Koen Deforche over 13 years ago
- Status changed from New to InProgress
- Target version changed from 3.1.10 to 3.1.11
Updated by Momo LALMI over 13 years ago
- File WVBoxLayout.png WVBoxLayout.png added
Hi Koen,
The main idea of the following widget is to show/hide/reorder columns in a WTreeView :
I am using a WVBoxLayout to hold all checkboxes, and two buttons to reorder the elements : (actions are : move up/down). When moving up/down WVBoxLayout elements on Google Chrome (latest): they disappear until the mouse is moved over the layout....
My WTreeView is connected to a model of type : dbo::QueryModel< dbo::ptr >();
My model does not react on ::removeColumns(....)
@@
//#############################################
// FILE : myWidget.h
//#############################################
#pragma once
#include
#include
namespace Wt
{
class WScrollArea;
class WIconPair;
class WPushButton;
class WCheckBox;
class WGridLayout;
class WHBoxLayout;
class WVBoxLayout;
}
using namespace Wt ;
using namespace std;
class MyWidget : public WDialog
{
public:
MyWidget(void);
~MyWidget(void);
private:
void move_up();
void move_down();
void item_clicked() ;
private:
WScrollArea * _scroll_area ;
WIconPair * _up ;
WIconPair * _down;
WPushButton * _apply ;
WPushButton * _close ;
WGridLayout * _grid ;
WVBoxLayout * _hbox;
//--------- check boxes ----------------
WCheckBox * id;
WCheckBox * start_date_time;
WCheckBox * end_date_time;
WCheckBox * duration;
WCheckBox * calling_number;
WCheckBox * calling_name;
WCheckBox * called_number;
WCheckBox * called_name;
WCheckBox * ring_duration;
WCheckBox * channel_number;
WCheckBox * channel_name;
WCheckBox * direction;
WCheckBox * username;
WCheckBox * short_comment;
WCheckBox * case_number;
WCheckBox * dtmf_received;
WCheckBox * dtmf_sent;
WCheckBox * signaling_src_ip;
WCheckBox * signaling_src_port;
WCheckBox * signaling_src_mac;
WCheckBox * signaling_dst_ip;
WCheckBox * signaling_dst_port;
WCheckBox * signaling_dst_mac;
WCheckBox * audio_src_ip;
WCheckBox * audio_src_port;
WCheckBox * audio_src_mac;
WCheckBox * audio_dst_ip;
WCheckBox * audio_dst_port;
WCheckBox * audio_dst_mac;
//---------------------------------------
WCheckBox * selected_item ;
};
//################################################
// FILE : MyWidget.h
//################################################
#include "Wt_RecordListColumnsWidget.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// boost headers ------------------
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/erase.hpp>
#include <boost/algorithm/string/find_format.hpp>
#include <boost/lexical_cast.hpp>
//---xml ---------------------------
#include <rapidxml.hpp>
#include <rapidxml_print.hpp>
//---std ---------------------------
#include
#include
#include
#include
#include
#include
// using namespace Wt;
using namespace std;
using namespace rapidxml;
//---------------------------------------------------------------------------------------------------------------------------
MyWidget::MyWidget(void)
//---------------------------------------------------------------------------------------------------------------------------
{
selected_item = NULL ;
this->setWindowTitle(tr("recordlist.columns"));
_grid = new WGridLayout();
_grid->setContentsMargins(10,10,10,10);
_scroll_area = new WScrollArea();
_scroll_area->resize( 300 , 400 ) ;
_scroll_area->setMinimumSize( 300 , 400 ) ;
_scroll_area->setScrollBarPolicy( WScrollArea::ScrollBarAsNeeded );
_scroll_area->setPositionScheme(Absolute);
_scroll_area->setMargin(10);
_hbox = new WVBoxLayout();
WContainerWidget * scrollContainer = new WContainerWidget();
_scroll_area->setWidget(scrollContainer );
scrollContainer->resize( WLength::Auto , WLength::Auto );
//scrollContainer->setMinimumSize(290, WLength::Auto );
scrollContainer->setLayout ( _hbox ) ;
// up button ----------------------------------------------------------------------------------
_up = new WIconPair( "icons/up_48.png","icons/up_48.png" );
_up->icon1Clicked().connect ( this, & Wt_RecordListColumnsWidget::move_up ) ;
_up->icon2Clicked().connect ( this, & Wt_RecordListColumnsWidget::move_up ) ;
_up->setToolTip(tr("recordlist.columns.up"));
// down button ----------------------------------------------------------------------------------
_down = new WIconPair( "icons/down_48.png","icons/down_48.png" );
_down->icon1Clicked().connect ( this, & Wt_RecordListColumnsWidget::move_down ) ;
_down->icon2Clicked().connect ( this, & Wt_RecordListColumnsWidget::move_down ) ;
_down->setToolTip(tr("recordlist.columns.down"));
//------- up down container ----------------------------------------------------------------
WContainerWidget * upDownContainer = new WContainerWidget();
upDownContainer->addWidget(_up);
upDownContainer->addWidget(new WBreak());
upDownContainer->addWidget(_down);
//---------------------- apply/close buttons ---------------------
WContainerWidget * buttonsContainer = new WContainerWidget();
WHBoxLayout * buttonsLayout = new WHBoxLayout();
buttonsContainer->setLayout( buttonsLayout ) ;
//---------- apply
_apply = new WPushButton( tr("recordlist.filterdialog.applybutton") );
_apply->clicked().connect( this, &Wt_RecordListColumnsWidget::accept);
_apply->resize( 80, 30 ) ;
_apply->setMaximumSize( 80, 30 ) ;
buttonsLayout->addWidget( _apply ) ;
//---------- cancel
_close = new WPushButton( tr("recordlist.filterdialog.closebutton") );
_close->clicked().connect( this, &Wt_RecordListColumnsWidget::reject);
_close->resize( 80, 30 ) ;
_close->setMaximumSize( 80, 30 ) ;
buttonsLayout->addWidget( _close ) ;
// check boxes ------------------
id = new WCheckBox(tr("recordlist.field.id"));
start_date_time = new WCheckBox(tr("recordlist.field.start_date_time"));
end_date_time = new WCheckBox(tr("recordlist.field.end_date_time"));
duration = new WCheckBox(tr("recordlist.field.duration"));
calling_number = new WCheckBox(tr("recordlist.field.calling_number"));
calling_name = new WCheckBox(tr("recordlist.field.calling_name"));
called_number = new WCheckBox(tr("recordlist.field.called_number"));
called_name = new WCheckBox(tr("recordlist.field.called_name"));
ring_duration = new WCheckBox(tr("recordlist.field.ring_duration"));
channel_number = new WCheckBox(tr("recordlist.field.channel_number"));
channel_name = new WCheckBox(tr("recordlist.field.channel_name"));
direction = new WCheckBox(tr("recordlist.field.direction"));
username = new WCheckBox(tr("recordlist.field.username"));
short_comment = new WCheckBox(tr("recordlist.field.short_comment"));
case_number = new WCheckBox(tr("recordlist.field.case_number"));
dtmf_received = new WCheckBox(tr("recordlist.field.dtmf_received"));
dtmf_sent = new WCheckBox(tr("recordlist.field.dtmf_sent"));
signaling_src_ip = new WCheckBox(tr("recordlist.field.signaling.src.ip"));
signaling_src_port = new WCheckBox(tr("recordlist.field.signaling.src.port"));
signaling_src_mac = new WCheckBox(tr("recordlist.field.signaling.src.mac"));
signaling_dst_ip = new WCheckBox(tr("recordlist.field.signaling.dst.ip"));
signaling_dst_port = new WCheckBox(tr("recordlist.field.signaling.dst.port"));
signaling_dst_mac = new WCheckBox(tr("recordlist.field.signaling.dst.mac"));
audio_src_ip = new WCheckBox(tr("recordlist.field.audio.src.ip"));
audio_src_port = new WCheckBox(tr("recordlist.field.audio.src.port"));
audio_src_mac = new WCheckBox(tr("recordlist.field.audio.src.mac"));
audio_dst_ip = new WCheckBox(tr("recordlist.field.audio.dst.ip"));
audio_dst_port = new WCheckBox(tr("recordlist.field.audio.dst.port"));
audio_dst_mac = new WCheckBox(tr("recordlist.field.audio.dst.mac"));
id->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
start_date_time->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
end_date_time->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
duration->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
calling_number->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
calling_name->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
called_number->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
called_name->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
ring_duration->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
channel_number->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
channel_name->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
direction->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
username->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
short_comment->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
case_number->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
dtmf_received->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
dtmf_sent->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
signaling_src_ip->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
signaling_src_port->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
signaling_src_mac->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
signaling_dst_ip->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
signaling_dst_port->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
signaling_dst_mac->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
audio_src_ip->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
audio_src_port->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
audio_src_mac->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
audio_dst_ip->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
audio_dst_port->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
audio_dst_mac->clicked().connect( this, & Wt_RecordListColumnsWidget::item_clicked ) ;
_hbox->addWidget(id);
_hbox->addWidget(start_date_time);
_hbox->addWidget(end_date_time);
_hbox->addWidget(duration);
_hbox->addWidget(calling_number);
_hbox->addWidget(calling_name);
_hbox->addWidget(called_number);
_hbox->addWidget(called_name);
_hbox->addWidget(ring_duration);
_hbox->addWidget(channel_number);
_hbox->addWidget(channel_name);
_hbox->addWidget(direction);
_hbox->addWidget(username);
_hbox->addWidget(short_comment);
_hbox->addWidget(case_number);
_hbox->addWidget(dtmf_received);
_hbox->addWidget(dtmf_sent);
_hbox->addWidget(signaling_src_ip);
_hbox->addWidget(signaling_src_port);
_hbox->addWidget(signaling_src_mac);
_hbox->addWidget(signaling_dst_ip);
_hbox->addWidget(signaling_dst_port);
_hbox->addWidget(signaling_dst_mac);
_hbox->addWidget(audio_src_ip);
_hbox->addWidget(audio_src_port);
_hbox->addWidget(audio_src_mac);
_hbox->addWidget(audio_dst_ip);
_hbox->addWidget(audio_dst_port);
_hbox->addWidget(audio_dst_mac);
int row = 0 ; int column = 0 ;
_grid->addWidget( _scroll_area , row , column , AlignTop | AlignLeft ) ;
column ;
_grid->addWidget( upDownContainer , row , column, AlignMiddle | AlignRight ) ;
column = 0 ; row ;
_grid->addWidget( buttonsContainer , row , column, 1 , 2 , AlignBottom | AlignCenter) ;
_grid->setRowStretch(0, 1 ) ;
_grid->setRowStretch(1, 0 ) ;
_grid->setColumnStretch( 0 , 1 ) ;
_grid->setColumnStretch( 1 , 0 ) ;
//----
this~~contents()>setLayout(_grid);insertWidget( index~~ 1 , selected_item ) ;
this->resize( 400 , 500 ) ;
}
//---------------------------------------------------------------------------------------------------------------------------
MyWidget::~MyWidget(void)
//---------------------------------------------------------------------------------------------------------------------------
{
}
//---------------------------------------------------------------------------------------------------------------------------
void MyWidget::move_up(void)
//---------------------------------------------------------------------------------------------------------------------------
{
if ( selected_item != NULL )
{
WWidgetItem* item = _hbox->findWidgetItem(selected_item);
if ( item != NULL )
{
int index = _hbox->indexOf( (Wt::WLayoutItem *)item ) ;
if ( index > 0 )
{
_hbox->removeWidget( selected_item ) ;
_hbox
}
}
}
_scroll_area->refresh();
}
//---------------------------------------------------------------------------------------------------------------------------
void MyWidget::move_down(void)
//---------------------------------------------------------------------------------------------------------------------------
{
if ( selected_item != NULL )
{
WWidgetItem* item = _hbox->findWidgetItem(selected_item);
if ( item != NULL )
{
int index = _hbox->indexOf( (Wt::WLayoutItem *)item ) ;
if ( index >= 0 )
{
_hbox->removeWidget( selected_item ) ;
_hbox->insertWidget( index + 1 , selected_item ) ;
}
}
}
_scroll_area->refresh();
}
//---------------------------------------------------------------------------------------------------------------------------
void MyWidget::item_clicked()
//---------------------------------------------------------------------------------------------------------------------------
{
selected_item = (WCheckBox *) this->sender();
}
Updated by Koen Deforche over 13 years ago
Hey,
Does the problem disappear when you do:
scrollContainer->setLayout ( _hbox, AlignJustify | AlignTop) ;
Regards,
koen
Updated by Koen Deforche over 13 years ago
Hey,
I could not reproduce the slowness --- see attached test case. Can you modify it so that it reproduces your problem ?
Regards,
koen
Updated by Koen Deforche over 13 years ago
- Status changed from InProgress to Feedback
Updated by Koen Deforche over 13 years ago
- Status changed from Feedback to Resolved
Updated by Koen Deforche about 13 years ago
- Status changed from Resolved to Closed
Resolved in Wt 3.1.11