Please could you give me an advice. I am using QSqlTableModel class to access the database table and QTableView to view it. What signal of what instance should I handle to know about user move the cursor in QTableView?
I want to update the content of TableView B after the cursor moved in QTableView A (Table B have foreign keys to table A in database)
May be somewhat from this http://doc.trolltech.com/latest/qabstractitemmodel.html?
Thanks.
Ivan, if you are talking about table cursor, you can reimplement QAbstractItemView::moveCursor method which is virtual.
If you're talking about mouse cursor, you can use QAbstractItemView::viewportEvent method to detect mouse move event. You need to set QWidget::setMouseTracking(true) to the viewport of your QTableView.
Hope that helps
Another way is using the selection model
Using a selection model
The standard
view classes provide default selection
models that can be used in most
applications. A selection model
belonging to one view can be obtained
using the view's selectionModel()
function, and shared between many
views with setSelectionModel(), so the
construction of new selection models
is generally not required.
If you have an shared selection model the views will be updated not matter which one changes. You can then react to it. The selection flags control if you want a cell, row or multiple selections.
See also working with selections :
//selection changes shall trigger a slot
QItemSelectionModel *selectionModel= treeView->selectionModel();
connect(selectionModel, SIGNAL(selectionChanged (const QItemSelection &, const QItemSelection &)),
this, SLOT(selectionChangedSlot(const QItemSelection &, const QItemSelection &)));
}
Related
I'm using EaselJS for a project, and have the need to store the details of various 'Shape' objects in a database, so that they can be re-drawn at another time.
My project has the 'Stage' set up so that I can drag-draw a box, which is saved into the database when completed. I intend to make it usable for drawing polygons also.
My database has a table in it called 'polyshapes', which stores the Shape.id, Shape.name, Shape.x, Shape.y, Shape.rotation. It also has a field called 'graphics' where I can store some sort of text string representing the Shape.graphics object.
When I draw a box, I'm able to store a string of the 'graphics' using: JSON.stringify(Myshape.graphics).
When I load this shape from the database, I create a new createjs.Shape() object, and then use Myshape.graphics = JSON.parse(graphicsString) to load the graphics.
Unfortunately this doesn't seem to work, as it doesn't load the required functions within the object.
I have also tried just individually updating some specific graphics attributes such as 'command', '_instructions', '_stroke', '_strokeStyle'. But I still can get the required graphic to re-draw.
Ideally, I'd only need to store the 'instructions' attribute of the Shape.graphics when I drag-draw it, and then when loading from the DB, I would just use a method to re-create those graphics when provided with the 'instructions' data. However I can't seem to see a suitable method for doing this.
I have also looked into the decodePath() graphics method. This would be useful, except that there doesn't appear to be an inverse method 'encodePath()' to allow me to serialize it in the first place.
How can I store the Shape.graphics data in a database, and then recall it later to rebuild a new Shape() object?
Thanks,
Hugh.
I am working on chat system, i have a conversation page with a list view inside it, the list view delegates are text conversations. I want to add seen/unseen or read/unread to conversation delegates, the list view sourced by a custom model and i need something like delegates attached property which changes when the delegate is actually being viewed. is there any attached property which tell me the visibility status of each delegate items?
You have two problems to solve:
How to store the information that the message has been viewd
When to set it as read.
So one after another...
The custom property within the delegate is no good idea, as the information stored in it will be lost once the delegate will leave the viewport of the ListView and is destroyed.
The best solution would be, to store it in the ListView's model. This way it is also possible, if the model is somewhat persistend, that the information survives a restart of the app.
Maybe you might achive something with the next options I will present, in combination with Settings but I would consider this hackish.
If that is not possible, and the information does not need to survive an app's restart, you need to think about a way of storing it outside the ListView. For example you could have a array or object/dictionary to store it (beware: No change notifications). You might also use a second ListView that you keep in sync (which might prove not so easy!).
Finally you might put your ListView as a model in an Instantiator, which instantiates simple QtObjects with one property: read.
The latter would be the easiest way to store it outside the delegates and the model, so I will show you how it works:
Instantiator {
id: additionalInfo
model: customModel
delegate: QtObject {
property bool read // <--- This is a custom defined property
}
}
ListView {
model: customModel
delegate: MyDelegate {
onRead: additionalInfo.objectAt(index).read = true
Text {
text: additionalInfo.objectAt(index).read ? 'read' : 'unread'
}
}
}
And now for the second part: When is it acutally read
The problem with the visibility you already discovered. Items become visible even outside the listView when they are created for the buffer. So you can't use this information. But you have the following information:
The position of the listModel.contentItem (x and y)
The position of the delegate in relation to the listModel.contentItem
The width and height of your delegate
So you can say: The delegate is fully visible iff:
listModel.contentItem.x + delegate.x >= 0
listModel.contentItem.y + delegate.y >= 0
listModel.contentItem.y + delegate.y + delegate.height <= listModel.height
listModel.contentItem.x + delegate.x + delegate.width <= listModel.width
An example, on how a Item might check if it is visible in a Flickable (remember: a ListView IS a Flickable) can be found here
This is: If it is possible to have the whole delegate with the view. If it is larger - well you need to define some criterias when the delegate is considered read.
But again: If there is any posibility to have it as a role in your model, put it there!
I have a model (let's call it M). This model has a relation (let's call it R) to an other model (X).
By default Gii generates the code which shows R as a numeric ID (primary key in the DB). I want to show it as a hyperlink.
I consider two ways to do it with zii.widgets.CDetailView:
provide extra arguments to $this->widget('zii.widgets.CDetailView');
define method getHyperlink() in my model class and refer to the property as ->hyperlink.
Which of these two ways is better?
The first way may require duplicate code (say in index.php with zii.widgets.CListView generated by Gii).
The second way requires attributeLabels() with new attribute hyperlink which would have the same title as an other (non-hyperlinked numeric) attribute. So I write the same title two times.
So, what of these two variants is better?
Generally, I would think that the second method using the model would be better due to being more DRY.
If you decide that you wanted to use the hyperlink inside of another view, then you would not have to redefine the logic with extra arguments to $this->widget('zii.widgets.CDetailView');
I have a set of groups of different types of item, all inheriting form a common base type (ItemBase). Each of my groups has an Items collection of type ObservableCollection<ItemBase>.
In my SemanticZoom.ZoomedInView, I can set a DataTemplateSelector, and in SelectTemplateCore() I can cast the item parameter to detrmine which template to apply.
In my zoomed out view, though, the objects are passed around as DependencyObjects, and I can't for the life of me figure out how I can take the data passsed in to determine which template to use.
To set the items source of the GridView in the zoomed out view, I use
(semZm.ZoomedOutView as ListViewBase).ItemsSource = this.groupedItemsViewSource.View.CollectionGroups;
as this appears to be the only way to get the zoomedin and zoomedout views to synchronise (when you click on a group in the zoomed out view it should take me to the appropriate place in the zoomedinview to see that group's detail.
So, am I missing something obvious in terms of getting the actual group in SelectTemplateCore(), or failing that is there a better way of binding my ItemsSource of the ZoomedOutView?
For the appropriate way to handle casting of the DependencyObject to a usable type, see the answer to This question.
Essentially, cast it to ICollectionViewGroup to access the members.
I am using a TreeView with a ListStore as model. When the user clicks on a row I want to take some action but not using the values in the cells, but using the data I created the row from...
Currently I have the TreeView, the TreeModel (ListStore) and my own data (which I ironically call model)..
So the Questions are:
Is it "right" to have a model - an object representation of the data I want to display and fill a ListStore with that data to display in a TreeView, or would it be better to implement an own version of TreeModel (wrapping my data-model) to display the data?
And also:
If someone double-clicks in a row I can get the RowActivated event (using C#/Gtk#) which provides a Path to the activated row. With that I can get a TreeIter and using that I can get the value of a cell. But what is the best practice to find the data object from which the row was constructed in the first place?\
(Somehow this question got me to the first one - by thinking would getting the data object more easy if I tried to implement my own TreeModel...)
It's quite awkward/difficult to implement TreeModel, so most people simply synch the data from their "real" model into a TreeStore or ListStore.
The columns in the store do not have to match the columns in the view in any way. For example, you can have a column that contains your real managed data objects.
When you add a cellrenderer to a TreeView (visual) column, you can add mappings between its properties and the columns of the store. For example, you could map one store column to the font of a text cellrenderer, and another store column to the text property of the same cellrenderer. Each time the cellrenderer is used to render a particular cell, the mappings will be used to retrieve the values from the store and apply them to the properties of the renderer before it renders.
Here's an example of a mapping:
treeView.AppendColumn ("Title", renderer, "text", 0, "editable", 4);
This maps store column 0 to the renderer's text GTK property and maps store column 4 to the editable property. For GTK property names you can check the GTK docs. Note that the example above uses a convenience method that adds a column, adds a renderer to it and add an arbitrary number of mapping via params. To add mappings directly to a column, for example a column with multiple renderers, pack the renderers into the column then use TreeViewColumn.AddAttribute or TreeViewColumn.SetAttributes.
You can also set up a custom data function that will be used instead of mappings. This allows you to set the properties of the renderer directly, given a TreeIter and the store - so, if all the data you want to display is trivially derived from your real data objects, you could even have your store only contain a single column of these objects, and use data funcs for all the view columns.
Here's an example of a data func that does exactly what the mapping example above does:
treeColumn.SetCellDataFunc (renderer, delegate (TreeViewColumn col,
CellRenderer cell, TreeModel model, TreeIter iter)
{
var textCell = (CellRendererText) cell;
textCell.Text = (string) model.GetValue (iter, 0);
textCell.Editable = (bool) model.GetValue (iter, 4);
});
Obviously data functions are much more powerful because they enable you not only to use properties of more complex GTK objects, but also to implement more complex display logic - for example, lazily processing derived values only when the cell is actually rendered.