Project

General

Profile

Actions

Bug #926

closed
ML KD

WBoxLayout : insert and remove operations are very very very slow

Bug #926: WBoxLayout : insert and remove operations are very very very slow

Added by Momo LALMI about 15 years ago. Updated almost 15 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Target version:
Start date:
07/24/2011
Due date:
% Done:

0%

Estimated time:

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

WVBoxLayout.png (26.3 KB) WVBoxLayout.png Momo LALMI, 07/25/2011 03:39 PM
test29.cc (2.95 KB) test29.cc Koen Deforche, 08/01/2011 10:37 AM

ML Updated by Momo LALMI about 15 years ago Actions #1

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)

KD Updated by Koen Deforche about 15 years ago Actions #2

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

KD Updated by Koen Deforche about 15 years ago Actions #3

  • Status changed from New to InProgress
  • Target version changed from 3.1.10 to 3.1.11

ML Updated by Momo LALMI about 15 years ago Actions #4

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 <Wt/WDialog>

#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 <Wt/WScrollArea>
#include <Wt/WIconPair>
#include <Wt/WPushButton>
#include <Wt/WCheckBox>
#include <Wt/WGridLayout>
#include <Wt/WHBoxLayout>
#include <Wt/WVBoxLayout>
#include <Wt/WBreak>
#include <Wt/WWidgetItem>
#include <Wt/WCssDecorationStyle>
// 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);
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
insertWidget( index~~ 1 , selected_item ) ;
}
}
}
_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();
}

KD Updated by Koen Deforche about 15 years ago Actions #5

Hey,

Does the problem disappear when you do:

scrollContainer->setLayout ( _hbox, AlignJustify | AlignTop) ;

Regards,
koen

KD Updated by Koen Deforche about 15 years ago Actions #6

Hey,

I could not reproduce the slowness --- see attached test case. Can you modify it so that it reproduces your problem ?

Regards,
koen

KD Updated by Koen Deforche about 15 years ago Actions #7

  • Status changed from InProgress to Feedback

KD Updated by Koen Deforche about 15 years ago Actions #8

  • Status changed from Feedback to Resolved

KD Updated by Koen Deforche almost 15 years ago Actions #9

  • Status changed from Resolved to Closed

Resolved in Wt 3.1.11

Actions

Also available in: PDF Atom