Following this question I have recently asked : Understanding Document.createElement()
Here is the context :
There is a text-zone in my GWT GUI that holds a text
Users can select a word (or a sequence of words) in this text-zone and transform it / them into a highlighted text
highlighted texts need to be able to listen to users : click, right-click, dragging & dropping operations
A scenario with 1000 highlighted text in the text-zone is not impossible.
I was wondering :
Is it a bad approach to manipulate DOM elements directly in GWT ? (Without using Widgets)
Is it a bad approach to do things like that Add listener to SpanElement ? Can it cause memory leaks ?
What is the best approach to achieve such things ? I've done some tests with a simple custom widget that uses a span element, and adding 1000 widgets to the RootPanel takes approximatively 6 to 10 seconds in DevMode. When I use DOM elements direclty, this operation duration goes under 1 second (even less than 200ms with optimizations).
EDIT
Performance should not be a problem, according to some real tests I did after #Gilberto advices. http://jmichelgarciagwt.appspot.com/DOMTesting.html
Still, I would love to have feedbacks for questions 1) and 2)
Adding listeners/handlers to hundreds of span elements/widgets is definitely a bad approach.
If you stay with GWT, you can attach a single event handler to your "text zone" widget, and then find which element has been the source of the click:
http://comments.gmane.org/gmane.org.google.gwt/61911
If you go with DOM elements, you can attach a single event listener to your "text zone" element and find out the event source when it bubbles to it. For example:
http://icant.co.uk/sandbox/eventdelegation/
Related
I am trying to create something similar to this in PyQt5:
https://www.screencast.com/t/1FikGosKbS
I tried using a separate QTextEdit widget for each bullet point and overriding the enter key to go to the next textbox, but I don't know how to make multiple QTextEdit widgets selectable (and able to copy paste) like in the example.
How can I allow the user to drag to select text across multiple QTextEdit boxes? Or is there a better approach to this?
I don't know this application is made from Qt or not,but I have an idea.
Parhaps you might have made the most part of this application... I can't know them from your question.I write my opinion on the premise that you don't know QText handling at all.
QTextEdit,QTextDocument,QTextCursor are used fully.
1.To understand block.
2.To use QTextBlockUserData(If you want.)
3.To use QGraphicsItem as nodes.
4.To go other page,we add a new QTextEdit on QStackedWidget or replace the QTextDocument of QTextEdit.
5.To make sub-nodes block,you can coordinate the indentation of blocks.
QTextBlock is a read-only data in a document.
You make QTextBlockUserData and set it to the block.
If you select multiple blocks you want to drag & drop , you use QTextCursor and movePosition methods with sequence.
The nodes of this application can not be QTextListFormat,because we cannot handle mouse click on the style.But you can insert empty-style QTextListFormat.
The truth of the nodes may be QGraphicsItem.
You can allocate it each the start position of blocks and the item can also have the block data.
It will difficult to take care of the connection between the nodes and the blocks.
In advance, you must set QGraphicsView & QGraphicsScene.
I insert many data on the container.
Which should we control with nodes or block?
My trial.
1.Nodes & Text
2.To the other page
3.Sub nodes & blocks
4.close sub nodes & blocks
My trial is incomplete,but it will be completed with endurance.
Logically,I think I can go step until the good point with these combinations.
But it will be diffcult...
These nodes are made from QGraphicsItem and allocated each Blocks.
You must calculate the position and recalculate during editing.
The mouse cursor image is deleted on these images.
It is outrange of screenshot.
I would like some help into speeding up the process of filtering a long list of list items and viewing them on a ListView.
My app has a search bar, a ListView and a very long list of strings to choose from.
When the user enter a search term, the ListView is updated with every key stroke and filter out the irrelevant items.
Sorting itself takes a few milliseconds, but updating the ListView afterwards with the new filter-event takes a long time (20 seconds easy, if only a single character has been entered as search criteria)
I believe the time is spent on inflating a large number of ViewCells every time the filtered list updates.
Do any of you know how to speed up the process? I thought the way it could work was to have a very limited number of ViewCells (like 10 or 20) and then have them update and just show a selection of the filtered list. Scrolling would to be reusing the top/bottom one, update the content and put it back on the bottom/top - but I have not been able to wrap my head around how to do this.
Maybe it is the wrong approach and you know a better way?
I just had a similar problem that my list with just 20 elements would search extremely slow. Maybe your problem is similar. Sadly you didn't post any code. I had something like this:
List l = originalItems.Where((i) => i.Name.Contains(filterText));
listView.ItemsSource = l;
And I could not understand why this would be so slow. I found a different approach with more overhead that for some reason is faster and more responsive and overall feels better for the user. My ListView always has an ObservableCollection as ItemsSource. When I filter I calculate the difference to this ObservableCollection (the extra items and the removed items) and then remove or add accordingly. This avoids replacing the ItemsSource property which seems to be too harsh on the ListView.
//property of the class
ObservableCollection<FlightListItem> listViewItems;
// ....
//somewhere at initialization
listView.ItemsSoure = listViewItems;
// ....
//in the filter method:
List l = originalItems.Where((i) => i.Name.Contains(filterText));
IEnumerable itemsToAdd = l.Except(listViewItems).ToList();
IEnumerable itemsToRemove = listViewItems.Except(l).ToList();
listView.BeginRefresh();
foreach (FlightListItem item in removes)
listViewItems.Remove(item);
foreach (FlightListItem item in added)
listViewItems.Add(item);
listView.EndRefresh();
Notes:
removing the listView.BeginRefresh() and EndRefresh() did not seem to impact performance, but it seems the right thing to call them here.
We need to call ToList() on the itemsToAdd and itemsToRemove even though we only need IEnumerables! This is because Except is a lazy operation and will otherwise only be evaluated during the for loop. However during the for loop one of the parameters to Except changes which leads to an IllegalArgumentException due to modifying an IEnumerable while going over it.
If anyone knows a good filterable observable collection that would probably be a nicer solution.
I have a collection of GtkEntry widgets, some of which are editable and focusable, and some of which are not. I would like to find out which, if any, of them currently has text selected, in order to implement an Edit->Copy menu item. Is there any way to do this other than iterating over all the widgets until gtk_editable_get_selection_bounds returns true?
I am currently sidestepping the issue by calling gtk_clipboard_get(GDK_SELECTION_PRIMARY) but from what the docs say, that's not portable (and will also pick up text selected anywhere within the current display, not just from within my application).
Have you tried gtk_window_get_focus ()? Users are frequently interacting with entries, so it may work for you. The documentation says that it "retrieves the current focused widget within the window." You can look it by yourself here. Then, compare if the widget retrieved is one of your entries.
Once you get the focused entry, perhaps you would like to get its text using gtk_entry_get_text () , though, it will get all the text in the entry. If this does not fit your purposes, the solution might be using gtk_editable_copy_clipboard () which copies the contents of the currently selected content in the editable (of course, cast the entry to editable) and puts it on the clipboard. Then if it applies, paste what was copied using gtk_editable_paste_clipboard ().
I'm building a Qt plugin with multiple forms. I have a main form which has a tree widget placed on the left of the form.
I want to add items to this tree, such that clicking on these items would load the corresponding form on the same form. But I want the tree widget to be active so that I can select any other form also.
I was able to display a form on the main form using the following code:
Form1 *myform;
myform=new Form1(this);
myform->show();
where Form1 is the class of the form i intend to display. However this, covers up the tree widget also. And I have to do a string comparison of the item in tree being clicked to display the appropriate form.
Can someone please help me with this as I'm very new to Qt programming.
Thanks
ixM has a good suggestion. The first step should definitely be to use layouts in your main window - separating the tree from the rest of the window - where you are going to put your form. I would suggest using a splitter, because then the user can resize the two halves. You can set the splitter as the main widget of your CentralWidget in your main window.
QSplitter splitter = new QSplitter(CentralWidget);
splitter->setOrientation(Qt::Horizontal);
splitter->setHandleWidth(3);
splitter->setChildrenCollapsible(false);
MyTree= new QTreeWidget(splitter);
splitter->addWidget(MyTree);
Then add your tree widget to the splitter, which will be on the left side.
The next step is to add a placeholder widget on the right side of your splitter. We are also going to add a layout inside that widget. This layout is very important we are going to use it later.
QWidget WidgetRightSide = new QWidget(splitter);
QVBoxLayout setupLayout= new QVBoxLayout(WidgetRightSide);
setupLayout->setSpacing(0);
setupLayout->setContentsMargins(0, 0, 0, 0);
Now, at this point, this is where my answer really differs from the previous answer. You could use a QStackedWidget. That is certainly an option. The problem with that is that you have to create and load all your forms at the beginning. That uses way more memory, and will take longer to start up. That's not so bad if you have 2-5 forms, but when we are talking about 20, 30 or more forms that's really ugly.
So what I would suggest instead, is that when the user selects something in the tree, we will remove the old form, and add the newly selected form at that point.
When the selected item in the tree changes this is now what we have to do.
First, remove all the stuff from the previously selection form.
QLayoutItem *_Item;
while ((_Item = setupLayout->takeAt(0)))
delete _Item;
Next, figure out what form to show next, and create it.
QWidget *ActiveSetupForm = NULL;
if ( I need to load form 1)
{
ActiveSetupForm = new YourNewForm( WidgetRightSide);
}
else ...
And lastly, add your new form to our layout.
if(ActiveSetupForm)
{
setupLayout->addWidget(pActiveSetupForm);
}
Just as a side note. Layouts are tricky to do by hand. I would strongly suggest that you look into using the QtDesigner when you are creating your forms. It makes life soooo much easier. If you would like to know more about it check out this link.
I don't exactly understand what you are trying to achieve but the bit of code you are showing suggests that you do not use the layouts provided by Qt.
If your goal is to be able to dynamically load a form depending on the item that was clicked in the tree, you could achieve that by having a layout (let's say QHBoxLayout) where you would insert your tree and a QStackedWidget in which you could "store" each form (by using addWidget()) and choose which one you want to display by calling setCurrentIndex().
I have a data-grid and three column in it. one column is type of DataGridViewComboBoxCell, three items are in this grid combo box, now i have to invoke selection index changed event to change value according to combo value change in grid.
also help me to make a new event ....
please help...
thanks
I really can't understand your question.
But maybe these informations can help:
A ComboBoxColumn has always two kinds of controls. A presenting one (in most cases a label) which is individually for each row. And a editing one that will be shared for the whole column. So take a look into this documentation and the IDataGridViewEditingControl Interface.
Maybe these will give you a starting point on how to solve your problem.
In the Load event for the form, you need to get the cell that you want to add the handler to and cast it as a regular combo box. You can then add the event handler on SelectedIndexChanged, but it must be done programmatically, and depending on the language you are using.