Re: [SailfishDevel] QSqlTableModel and running several remorses
Hi, Allright, I've done some further testing and I also read some parts of the QSqlTableModel source code to understand what's going on. I've finally managed to get something working. For people that might be interested in it, I figured out that : - You have to emit the `beginRemoveRows` and `endRemoveRows` signals when removing an item from the model. The provided implementation of `removeRows` doesn't do it for you (that was my main issue) ; - You have to use `OnManualSubmit` strategy. Using `OnFieldChange` strategy has some side-effects that will cause either a segfault or wrong data being manipulated (when several remorses are running at the same time) ; - Since you have to use `OnManualSubmit`, you also have to call `submitAll` at some point to "commit" the changes made on the model. If you don't call it or if your app crashes before, all the changes will be lost (which, IMHO, is a major drawback). If someone knows an app that uses a QSqlTableModel, I'd be interested in reading the source code to see if there is another solution. Feel free to add whatever you want that could help me :) PS: I haven't investigated the proxy approach yet. I'll probably give it a try in the next few days. Cheers, -- François - Mail original - > Hi, > > I've stumbled upon something very annoying : > > I have a model that inherits from QSqlTableModel. A SilicaListView > shows the data. This is very easy to do, thanks to Qt/QML :) > > Each list item has a ContextMenu with a "Delete" entry that allows > the user to delete the item. It runs a remorse, and, at the end of > the remorse, the item is deleted from the model (and the database). > Again, this works quite well... until you try to delete several items > at the same time > > A QSqlTableModel can have 3 different edit strategies : > OnManualSubmit, OnRowChange or OnFieldChange. > > If I set it to "OnManualSubmit", the item is deleted from the model, > but it remains in the view and in the database until I call > QSqlTableModel::submitAll(). This method actually commits the > changes to the database, and resets the model by calling > QSqlTableModel::select(). Since the model is resetted, it loses all > other running remorses and causes a segfault. > > If I set it to "OnFieldChanged", the item is deleted from the model > and from the database, but it will still remain visible in the view. > According to the Qt doc, I should call select() to update the view. > But, as we've seen before, this destroys the other running remorses > and also causes a segfault. > > > I've made a very small app to demonstrate the problem, you can get it > here and try it in your emulator : git clone > https://github.com/Frzk/dummy.git > You can use the PullDownMenu to switch between OnManualSubmit and > OnFieldChanged strategies. > > > > How should I deal with this ? This is a very simple case, yet I can't > seem to find a solution :( > > > > All the best, > > -- > François > ___ SailfishOS.org Devel mailing list To unsubscribe, please send a mail to devel-unsubscr...@lists.sailfishos.org
Re: [SailfishDevel] QSqlTableModel and running several remorses
Hi Peter, hi guys, First, thanks for your answer and ideas :) > I find your code a bit hard to read. It would be nice if you use full > names like list instead of l. I know it is annoying, but makes live > easier in the long run. Yeah, sorry about that. I'm not used to working in team and I also avoid variable names that can look like keywords (i.e. "list"). I also always use "r" for the variable that is returned. I have uploaded a new version of the code with "l" replaced with "list" and some more comments. If you have other remarks, please tell me, I'll try to improve that :) > Why do you have more then one Remorse? This is not clear to me. Maybe > you can explain? Well it's seems pretty obvious : I want to remove several items from the list, one after the other. When you do this quickly, several remorses can run at the same time. > Where do you close your db connection? - May I have overlooked this > :( You didn't overlooked it. I don't close it in the small example I wrote. In my real app, I have a "Storage" class that opens the database when the app starts and closes it when the object is destroyed. > Could not find the method Match in the documentation or in the code > :(. > > QModelIndexList l = this -> match ( this -> index ( 0 , 0 ), > MModel::IdRole, itemId, 1 , > Qt::MatchExactly); > > I check against http://doc.qt.io/qt-5/qsqltablemodel.html What is > your reference? It's inherited from QAbstractItemModel : http://doc.qt.io/qt-5/qabstractitemmodel.html#match > SQLLite may only support multiple readers or one writer. Maybe this > is your Problem? I don't think so, I'm writing (deleting) one item after another. > I would honestly have One Data Object that knows how to read from the > DB and open and closes the Connection for each operation with the DB > seperatly. > Not sure if this solves you Problem but it makes it easier to debug > and Maintain. (Maybe Code is slower... But I rather have a rugged > Code then a fast one.) > > I would think in Layers: > USER > VIEW > APPDATAMODEL > DATABASE CONNECTOR > DATABSE I'm not sure that would make a difference here but I will definitely consider this, thanks :) > Hope this helps you a bit. Of course it does :) Thanks a lot, Cheers, -- François ___ SailfishOS.org Devel mailing list To unsubscribe, please send a mail to devel-unsubscr...@lists.sailfishos.org
Re: [SailfishDevel] QSqlTableModel and running several remorses
Hi, Thanks for your input :) > Hi, I am a SQL noob, but here's my piece of advice: > Use a QML list model as a "proxy" and then replace the database with > the QML list model's data at some point, like after the user exits > some sort of list edit mode. It might not be the most efficient way > but it works and is really easy, you just need a loop that throws > all the things from the QML list model into the SQL database and > another one to do this the other way around. How would you make such a thing ? Use the destructor of the proxy to update the database ? I have to admit that I don't really like this approach, it sounds kinda risky to me. And it also means that I have to add extra loops for something that shouldn't require it. But I'll probably give it a try if I don't get any other lead :) Thanks again :) -- François ___ SailfishOS.org Devel mailing list To unsubscribe, please send a mail to devel-unsubscr...@lists.sailfishos.org
Re: [SailfishDevel] QSqlTableModel and running several remorses
Hello, I sent the following email a few weeks ago but got no answer. The github statistics also show that only one person downloaded the "dummy" project I wrote to demonstrate my issue... :( With the recent announcements and the Jolla boat sailing on, I'd like to get this solved. I'm even willing to pay if necessary. Thanks a lot, All the best, - Mail original - > > I have a model that inherits from QSqlTableModel. A SilicaListView > shows the data. This is very easy to do, thanks to Qt/QML :) > > Each list item has a ContextMenu with a "Delete" entry that allows > the user to delete the item. It runs a remorse, and, at the end of > the remorse, the item is deleted from the model (and the database). > Again, this works quite well... until you try to delete several items > at the same time > > A QSqlTableModel can have 3 different edit strategies : > OnManualSubmit, OnRowChange or OnFieldChange. > > If I set it to "OnManualSubmit", the item is deleted from the model, > but it remains in the view and in the database until I call > QSqlTableModel::submitAll(). This method actually commits the > changes to the database, and resets the model by calling > QSqlTableModel::select(). Since the model is resetted, it loses all > other running remorses and causes a segfault. > > If I set it to "OnFieldChanged", the item is deleted from the model > and from the database, but it will still remain visible in the view. > According to the Qt doc, I should call select() to update the view. > But, as we've seen before, this destroys the other running remorses > and also causes a segfault. > > I've made a very small app to demonstrate the problem, you can get it > here and try it in your emulator : git clone > https://github.com/Frzk/dummy.git > You can use the PullDownMenu to switch between OnManualSubmit and > OnFieldChanged strategies. > > How should I deal with this ? This is a very simple case, yet I can't > seem to find a solution :( -- François ___ SailfishOS.org Devel mailing list To unsubscribe, please send a mail to devel-unsubscr...@lists.sailfishos.org
[SailfishDevel] QSqlTableModel and running several remorses
Hi, I've stumbled upon something very annoying : I have a model that inherits from QSqlTableModel. A SilicaListView shows the data. This is very easy to do, thanks to Qt/QML :) Each list item has a ContextMenu with a "Delete" entry that allows the user to delete the item. It runs a remorse, and, at the end of the remorse, the item is deleted from the model (and the database). Again, this works quite well... until you try to delete several items at the same time A QSqlTableModel can have 3 different edit strategies : OnManualSubmit, OnRowChange or OnFieldChange. If I set it to "OnManualSubmit", the item is deleted from the model, but it remains in the view and in the database until I call QSqlTableModel::submitAll(). This method actually commits the changes to the database, and resets the model by calling QSqlTableModel::select(). Since the model is resetted, it loses all other running remorses and causes a segfault. If I set it to "OnFieldChanged", the item is deleted from the model and from the database, but it will still remain visible in the view. According to the Qt doc, I should call select() to update the view. But, as we've seen before, this destroys the other running remorses and also causes a segfault. I've made a very small app to demonstrate the problem, you can get it here and try it in your emulator : git clone https://github.com/Frzk/dummy.git You can use the PullDownMenu to switch between OnManualSubmit and OnFieldChanged strategies. How should I deal with this ? This is a very simple case, yet I can't seem to find a solution :( All the best, -- François ___ SailfishOS.org Devel mailing list To unsubscribe, please send a mail to devel-unsubscr...@lists.sailfishos.org
Re: [SailfishDevel] UX issues
Thank you Petr for you advices. I'll definitely give it a try. If others have other ideas/advices/points of view, please share them ! Cheers, -- François ___ SailfishOS.org Devel mailing list To unsubscribe, please send a mail to devel-unsubscr...@lists.sailfishos.org
[SailfishDevel] UX issues
Hi, I have yet another UX/UI issue. I'll try to be as concise as possible, but this post might end a bit long. Sorry for that. I'm also sorry if it sounds easy to solve, or out of topic for some of you. Just tell me. Please consider the following (basic) scenario : My app allows the user to manage a list of Things (what a Thing is isn't very important). The first page of the app is a SilicaListView listing all the Things. These Things have several properties. Some of these properties can be added, edited or removed. 1. First issue : From the first page, when tapping on a Thing, what are you expecting ? A - A new Page **shows** the details about the tapped Thing ? B - A new **Page** allows you to **Edit** the details ? C - A new **Dialog** allows you to **Edit** the details ? 2. For now, looking at the Jolla apps (especially the calendar), I've made the choice A, which brings other issues... Let's say that one (or more) property(ies) of the Thing can be represented as a list (ig. a list of tags, a list of side-notes, a list of participants, ...) So, I'm on my Page with all the details about my Thing. How do I edit that kind of "list-property" (by editing I mean adding, modifying and deleting item(s) from the list) ? A - I tap anywhere on the list. A new **Dialog** (with the very same list) opens where I can : * use a PullDownMenu to add a new entry (note that PullDownMenu in Dialog are not so OK), * use ContextMenu to edit or remove items. B - I tap anywhere on the list. A new **Page** (with the very same list) opens where I can : * use a PullDownMenu to add a new entry (better than the Dialog), * use ContextMenu to edit or remove items. C - I tap and hold an item to show a ContextMenu that allows me to edit/remove the item. But how do I add a new item ? C-a ) A TextField at the bottom of the list allows me to do so, C-b ) A "Add new" **ListItem** at the bottom of the list opens a new Dialog with a TextField, C-c ) A "Add new" **Button** at the bottom of the list opens a new Dialog with a TextField. 3.1. Again, for now, I think the most sailfishy way to do this is to use A. The issue here is as follows : if I want to add a new item to a list~property, I have to : 1. tap on the Thing (opens a new Page with all details) ; 2. tap on the list~property I want to edit (opens a new Dialog) ; 3. pull down the menu and chose 'New item' (opens a new Dialog) ; 4. type text ; 5. accept the 1st Dialog ; 6. accept the 2nd Dialog ; 7. back to the details Page. It's a rather long/complex process, isn't it ? 3.2. Now let's see with the C. proposal : If I want to add a new item a list~property of my Thing, I have to : 1. tap on the Thing (opens a new Page with all details) ; 2.a add a new item to the list~property (directly with option C-a) or... 2.b tap a ListItem or a Button (option C-b and C-c) and 2.b.1 fill the TextField, 2.b.2 accept the Dialog 2.b.3 back to the details Page. The process is quicker, but it feels weird to be able to edit a property on what is supposed to be a view-details-only-page... Which leads back to the first issue... As you can see I'm a bit lost. I would appreciate any help and comments regarding this. Thanks :) -- François ___ SailfishOS.org Devel mailing list To unsubscribe, please send a mail to devel-unsubscr...@lists.sailfishos.org
Re: [SailfishDevel] New documentation on sailfishos.org
I was more thinking about a centralized place. IMHO, having 2 places to check adds confusion, especially when you are new in the community. I was thinking about a git repo with .md files. People who would want to contribute would just have to send a PR. If accepted, Jolla would just have to hook it to the website. I have nothing against mer wiki, obviously :) -- François Envoyé depuis mon Jolla ___ SailfishOS.org Devel mailing list To unsubscribe, please send a mail to devel-unsubscr...@lists.sailfishos.org
Re: [SailfishDevel] Build a Model with fixed items + dynamic ones
Hi Peter, Thanks for your answer and your time :) I dont get it. A project status is a perfect field for a DB. The query would even group the project in the right way. select status , projectname from todolist group by statusRank ; Currently, a task is represented that way : uuid, description, status, due_date, project, [several others fields...] A task *MUST* have a uuid, a description and a status (status being either 'pending', 'completed', 'deleted'). A task *CAN* have a due_date and CAN have a project. With this, I want the first item of my list to be Today (so the user can quickly access all the tasks he has to do today). When the user selects this item, he would get a list of all tasks for which due_date is set and equals today, regardless of the project field (the user would get tasks from project 'Super project', 'House building', 'New server', and also tasks that don't have a project set. The second item of the list would be Overdue, and would list all tasks that have a due_date which is past today, also regardless of the project field. I have 6 fixed items like these. Then, I want the user to be able to access his projects. So I'd like to list the existing projects (this is the dynamic part of the model) : Super project would list all tasks that have the project field set to Super project. In this case, I don't care about the due_date field. I just want the task belonging to this project. then you could have some code that goes through the objects print project { arraycontainer.projectname } If (arraycontainer[i+1].status arraycontainer[i].status) { print new_cat() }; sorry for the bad pseudocode but i hope you get the idea.my c++ is not good and i want to go to bed. Nah, don't apologize, thank *you* for taking some time and trying to help me :) Cheers, -- François ___ SailfishOS.org Devel mailing list To unsubscribe, please send a mail to devel-unsubscr...@lists.sailfishos.org
Re: [SailfishDevel] Build a Model with fixed items + dynamic ones
Hi Nils, Wow, thanks *a lot* ! I totally overlooked the user of QAbstractProxyModel. This could definitely help if I choose n°1 idea. I'd still have to figure out how to deal with the refreshing part, but that's a strong way to get started. Thanks a lot, I wasn't asking for so much stuff/code :) (Would you mind if I put your names in the credits (Lucien, Michael, Peter, Nils) ?) -- François - Mail original - Hi, On Fri, Apr 17, 2015 at 12:09 PM, François K. daithe...@free.fr wrote: 1/ The first one is to build a Model that would inherit from QAbstractListModel. In the constructor, I would add the first 6 items (hard-code them). maybe this code can give you some inspiration to solve at least some part of your problem: -- prefixmodel.h #ifndef PREFIXMODEL_h #define PREFIXMODEL_h #include QAbstractProxyModel class RealModel; class PrefixModel : public QAbstractProxyModel { Q_OBJECT public: explicit PrefixModel(QObject *parent = 0); int rowCount(const QModelIndex parent = QModelIndex()) const; int columnCount(const QModelIndex parent) const { return 1; } QModelIndex parent(const QModelIndex ) const { return QModelIndex(); } QModelIndex index(int row, int column, const QModelIndex parent = QModelIndex()) const; QModelIndex mapFromSource(const QModelIndex sourceIndex) const; QModelIndex mapToSource(const QModelIndex proxyIndex) const; void setRealModel(RealModel *sourceModel) private slots: void sourceRowsInserted(const QModelIndex , int, int); void sourceRowsRemoved(const QModelIndex , int, int); void sourceRowsAboutToBeInserted(const QModelIndex , int, int); void sourceRowsAboutToBeRemoved(const QModelIndex , int, int); void sourceReset(); QVariant data(const QModelIndex proxyIndex, int role) const; }; #endif // PREFIXMODEL_h -- prefixmodel.cpp #include prefixmodel.h #incldue realmodel.h #define FIX_ITEMS 6 PrefixModel::PrefixModel(QObject *parent) : QAbstractProxyModel(parent) { } QModelIndex PrefixModel::mapFromSource(const QModelIndex sourceIndex) const { return sourceModel()-index(sourceIndex.row() + FIX_ITEMS, sourceIndex.column()); } QModelIndex PrefixModel::mapToSource(const QModelIndex proxyIndex) const { if (!sourceModel()) return QModelIndex(); return sourceModel()-index(proxyIndex.row() - FIX_ITEMS, proxyIndex.column()); } QVariant PrefixModel::data(const QModelIndex proxyIndex, int role) const { if (proxyIndex.row() FIX_ITEMS) { if (role == Qt::DisplayRole) return QString(fix item #%1).arg(proxyIndex.row()); return QVariant(); } return QAbstractProxyModel::data(proxyIndex, role); } int PrefixModel::rowCount(const QModelIndex parent) const { if (!sourceModel()) return 0; return sourceModel()-rowCount(parent) + FIX_ITEMS; } QModelIndex PrefixModel::index(int row, int column, const QModelIndex parent) const { return createIndex(row, column, 0); } void PrefixModel::setRealModel(RealModel *sourceModel) { if (this-sourceModel() == sourceModel) return; if (this-sourceModel()) this-sourceModel()-disconnect(this); QAbstractProxyModel::setSourceModel(sourceModel); emit sourceModelChanged(); connect(sourceModel, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), this, SLOT(sourceRowsAboutToBeInserted(QModelIndex,int,int))); connect(sourceModel, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(sourceRowsInserted(QModelIndex,int,int))); connect(sourceModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(sourceRowsAboutToBeRemoved(QModelIndex,int,int))); connect(sourceModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(sourceRowsRemoved(QModelIndex,int,int))); connect(sourceModel, SIGNAL(modelReset()), this, SLOT(sourceReset())); } RealModel *PrefixModel::sourceModelInternal() const { return qobject_castRealModel*(QAbstractProxyModel::sourceModel()); } void PrefixModel::sourceRowsInserted(const QModelIndex , int start, int end) { endInsertRows(); } void PrefixModel::sourceRowsRemoved(const QModelIndex , int start, int end) { endRemoveRows(); } void PrefixModel::sourceRowsAboutToBeInserted(const QModelIndex , int start, int end) { beginInsertRows(QModelIndex(), start + FIX_ITEMS, end + FIX_ITEMS); } void PrefixModel::sourceRowsAboutToBeRemoved(const QModelIndex , int start, int end) { beginRemoveRows(QModelIndex(), start + FIX_ITEMS, end + FIX_ITEMS); } void PrefixModel::sourceReset() { beginResetModel(); endResetModel(); } Nils ___ SailfishOS.org Devel mailing list To unsubscribe, please send a mail to devel-unsubscr...@lists.sailfishos.org ___ SailfishOS.org Devel mailing list To unsubscribe, please send a mail to devel
Re: [SailfishDevel] Build a Model with fixed items + dynamic ones
Hi Michael, hi Lucien, hi devs, I support this idea: Why don't you build a model that is built in two step during creation, first, build the 6 entries, then build the rest ? Do you suggest to do this in C++ (which is my idea n°1) or mix C++ and QML (see below) ? Is'nt it possible to add the items in the QML-part? I don't know... I just don't know how to do this with QML :/ With a SilicaListView, I guess Qt would overwrite the fixed items as soon as I set the model property on the SilicaListView, wouldn't it ? Cheers, -- François ___ SailfishOS.org Devel mailing list To unsubscribe, please send a mail to devel-unsubscr...@lists.sailfishos.org
Re: [SailfishDevel] Build a Model with fixed items + dynamic ones
Hi Lucien, Thanks a lot for your blazingly fast answer :D Can't you simply make the hard-coded entries dynamic too. Just add a column in the db saying that these entries are the hardcoded ones ? Sadly, nope, I can't hard-code them in the database because they are entry point to a different view on the same data. To make things more clear, I'm building a to-do app. The first screen is a list where the first items are : Today, Overdue, Completed, Trash, ... And then, I want to have the list of Projects (which are gathered from the database entries). Today, Overdue, etc... can't be added as Projects in the database, it makes no sense :( And when doing db stuff, don't forget to use transactions. It can help speeding up stuff a lot. Thanks for this advice. I'll do my best to respect this and use transactions everywhere. Cheers, -- François ___ SailfishOS.org Devel mailing list To unsubscribe, please send a mail to devel-unsubscr...@lists.sailfishos.org
Re: [SailfishDevel] Update previous page
Hi Florian, When you mark a file as read, your model should be updated and the list on the previous page should be updated accordingly (this is done automatically). Hope this can help you. À mar. mars 17 13:01:04 2015 GMT+0100, Florian Desneux a écrit : Hello, I'm wondering how can I refresh the page when the little white round in the corner is clicked or a swipe left to right from the corner is triggered? Meaning: I'm on my 3th app page, I trigger an action (i.e. mark as read the file), I go back to my 2th page on which there is a list of files. How can I update the list's item (the file) so it's displayed as 'read' (i.e. with an eye icon)? Summary: How can I pass back some properties? (Those three questions are the same ;) ). Regards, -- *Florian Desneux* -- François Envoyé depuis mon Jolla ___ SailfishOS.org Devel mailing list To unsubscribe, please send a mail to devel-unsubscr...@lists.sailfishos.org
Re: [SailfishDevel] Wrap data in Item to get notifiable properties ?
Hi, It is a good practice to load the minimal amount of data in a ListModel. I don't know which app you are developing, but for an example TODO list app, the main page would only load (from a storage, like a database), only the title and id of the TODO entries. Clicking on an entry will trigger the load of the full TODO entry from the database, based on the id. That's exactly what I'm doing right now (a Tasks app + just load the minimum amount of data required for the list + load the full Task properties when entering the DetailsView). Usual application goes from less detailed to more detailed information (all TODO entries - one TODO entry, all friends - one friend's wall - one post etc.), so I wonder why you have to modify the ListModel when you pushed the page ? Isn't that what you suggested in your previous answer (when I was trying to get notifiable properties) ? I'm confused (and also sorry, because I really guess it's a very trivial issue :( ) If you want to modify the model nevertheless, I think that the best way would be to provide a signal in your sub-page, that is emitted and caught in the main page in order to call model.set. This is better than passing the model, as the sub-page and page are more separated. Ok, I'll keep that in mind, thanks :) Thanks again... -- François ___ SailfishOS.org Devel mailing list To unsubscribe, please send a mail to devel-unsubscr...@lists.sailfishos.org
[SailfishDevel] Wrap data in Item to get notifiable properties ?
Hi, I'm writing a small app for SailfishOS in JS + QML (I don't know C++ so please don't tell me to do this in C++). I'm getting data from LocalStorage and hence get a Javascript Object with its own properties. Let's call it myObj. Then I bind some field in a view to these properties : DetailItem { label: qsTr(MyProp) value: myObj.myProp } Now, if I update myObj.myProp, the value of the DetailItem doesn't get updated. For what I understand, this is normal because the properties of my Javascript Object (myObj) aren't notifiable and thus, QML doesn't know it has been updated. To fix this, I wonder if it's OK to wrap my JS object into a QML Item. This would give me notifiables properties and would certainly allow me to get working bindings. What do you think about this ? Is it OK ? Thanks a lot for your help, Best wishes, -- François ___ SailfishOS.org Devel mailing list To unsubscribe, please send a mail to devel-unsubscr...@lists.sailfishos.org
Re: [SailfishDevel] Wrap data in Item to get notifiable properties ?
Hi, @Lucien : thanks again for your help. I'm starting to owe you a lot :) - Mail original - The best way to do this is to use QML ListModel. Instead of loading the properties in a JS object, you can load them as model properties (via http://qt-project.org/doc/qt-5/qml-qtqml-models-listmodel.html#set-method). Accessing the properties would be done via model: DetailItem { label: qsTr(MyProp) value: model.myProp } I see. Since I already have a ListModel for the previous view (basically, a list), I'm now wondering if I'd best : 1. Load everything in the ListModel and just go on with it (but what about memory consumption if the ListModel is big ?) ; or : 2. Load the minimum amount of data in the ListModel for the ListView, and when I enter the DetailsView, load the additional data and modify the ListModel via set(...) or setProperty(...). Is there a preferred way ? If you don't want to use a ListModel, prefer using QtObject instead of Item. QtObject provides a non-graphical component to store properties, unlike Item that implies having a box (x, y, width, height, anchors etc.) Oh yes, sure ! How could I miss that one ? :( I think I'll try to stick with the ListModel, it'll probably solve another issue :) Best regards, -- François ___ SailfishOS.org Devel mailing list To unsubscribe, please send a mail to devel-unsubscr...@lists.sailfishos.org
Re: [SailfishDevel] SearchField Mystery
Hi Krisztian, I faced the same issues last week, and solved it this way : http://pastebin.com/8JRd3ATp (borrowed from the SearchField example provided by Jolla). I tried several things, it's the only one that seems to give the expected result. But I don't know why :/ Cheers, -- François ___ SailfishOS.org Devel mailing list To unsubscribe, please send a mail to devel-unsubscr...@lists.sailfishos.org
[SailfishDevel] ComboBox init
Hi :) I have a ComboBox issue ! The ComboBox I want to use is made of dynamic items. I build it with a ListModel and a Repeater as follow : ComboBox { id: project label: qsTr(Project) menu: ContextMenu { MenuItem { text: qsTr(Not set) } Repeater { model: ProjectsModel { id: projects } delegate: MenuItem { text: model.value } } } } It works pretty well (yay QML !). Now I would like to initialize the ComboBox value. I tried several things (see after) and none of them worked. I hope you guys can give me some help/tip :) 1. First I tried to set its value directly. It doesn't really work well : the text that appears is the good one, but when I open the ComboBox to chose another value, the highlighted item is not the good one (which means that the ComboBox doesn't compute currentIndex and currentItem automagically when one set the ComboBox value). Moreover, when I select another item in the menu, the currentIndex and currentItem are changed as expected, but the value of the ComboBox doesn't change ! Here is the code that highlights the problem : ComboBox { id: project label: qsTr(Project) menu: ContextMenu { MenuItem { text: qsTr(Not set) } Repeater { model: ProjectsModel { id: projects } delegate: MenuItem { text: model.value } } } value: Some Value onCurrentIndexChanged: { console.log(currentIndex just changed to : , currentIndex); } onCurrentItemChanged: { console.log(currentItem just changed to : , currentItem.text); } onValueChanged: { console.log(value just changed to : , value); } } And the output : [D] onValueChanged:159 - value just changed to : Foo [...] [D] onCurrentItemChanged:155 - currentItem just changed to : Bar [D] onCurrentIndexChanged:151 - currentIndex just changed to : 2 What I expected to see : [D] onValueChanged:159 - value just changed to : Foo [...] [D] onCurrentItemChanged:155 - currentItem just changed to : Bar [D] onCurrentIndexChanged:151 - currentIndex just changed to : 2 [D] onValueChanged:159 - value just changed to : Bar 2. Then I tried to set currentIndex. There, for some reason that I don't explain, it seems that the ComboBox always reset it to 0 : Component { // Some other stuff here ComboBox { id: project label: qsTr(Project) menu: ContextMenu { MenuItem { text: qsTr(Not set) } Repeater { model: ProjectsModel { id: projects } delegate: MenuItem { text: model.value } } } onCurrentIndexChanged: { console.log(currentIndex just changed to : , currentIndex); } onCurrentItemChanged: { console.log(currentItem just changed to : , currentItem.text); } onValueChanged: { console.log(value just changed to : , value); } } Component.onCompleted: { // Here I get the task object from the database. var task = Storage.getTask(id); if(task !== null) { for(var i=0 ; iprojects.count ; i++) { if(task.project === projects.get(i).value) { project.currentIndex = i + 1; // We have to +1 because of the Not set MenuItem. break; } } } } } And the output : [D] onCurrentIndexChanged:151 - currentIndex just changed to : 2 [D] onCurrentIndexChanged:151 - currentIndex just changed to : 0 Do you guys have any idea on what's going on ? By the way, I think it could be great for the ComboBox to behave like HTML’s select : MenuItem could have a text and a value property. Setting a ComboBox value would automatically update currentItem and currentIndex. Something like this : ComboBox { menu: ContextMenu { MenuItem { text: qsTr(Some item) value: some_item } MenuItem { text: qsTr(Another item) value: another_item } } Component.onCompleted: { value = another_item; // This would highlight the second item, set currentIndex to 1 and currentItem accordingly. } } Of course, one could still set currentIndex or currentItem, and it would update everything accordingly. Also, the MenuItem value would default to the text value if the value is not explicitly set. I'd be glad to work on this if you agree :) Thanks for your attention. My best wishes, -- François ___ SailfishOS.org Devel mailing list To unsubscribe, please send a mail to devel-unsubscr...@lists.sailfishos.org
Re: [SailfishDevel] ComboBox issue (initialization)
Hi ! - Mail original - Hello. You need to set currentIndex after your model data initialized, not object. You can initialize at onCountChanged or make special signal from signal and listen it. Thanks a lot Andrey, that solved my problem. I think I need some doc about that kind of stuff (data initialization, where to put it, how, when, why...). Does someone have any good pointer about these issues ? Thanks, -- François ___ SailfishOS.org Devel mailing list To unsubscribe, please send a mail to devel-unsubscr...@lists.sailfishos.org
[SailfishDevel] ComboBox issue (initialization)
Hi :) I have a ComboBox issue ! The ComboBox I want to use is made of dynamic items. I build it with a ListModel and a Repeater as follow : ComboBox { id: project label: qsTr(Project) menu: ContextMenu { MenuItem { text: qsTr(Not set) } Repeater { model: ProjectsModel { id: projects } delegate: MenuItem { text: model.value } } } } It works pretty well (yay QML !). Now I would like to initialize the ComboBox value. I tried several things (see after) and none of them worked. I hope you guys can give me some help/tip :) 1. First I tried to set its value directly. It doesn't really work well : * The text that appears is the good one - OK * When I open the ComboBox to chose another value, the highlighted item is not the good one (which means that the ComboBox doesn't compute currentIndex and currentItem automagically when one set the ComboBox value) ; * Moreover, when I select another item in the menu, the currentIndex and currentItem are changed as expected, but the value of the ComboBox doesn't change. Here is the code that highlights the problem : ComboBox { id: project label: qsTr(Project) menu: ContextMenu { MenuItem { text: qsTr(Not set) } Repeater { model: ProjectsModel { id: projects } delegate: MenuItem { text: model.value } } } value: Some Value onCurrentIndexChanged: { console.log(currentIndex just changed to : , currentIndex); } onCurrentItemChanged: { console.log(currentItem just changed to : , currentItem.text); } onValueChanged: { console.log(value just changed to : , value); } } And the output : [D] onValueChanged:159 - value just changed to : Foo [...] [D] onCurrentItemChanged:155 - currentItem just changed to : Bar [D] onCurrentIndexChanged:151 - currentIndex just changed to : 2 What I expected to see : [D] onValueChanged:159 - value just changed to : Foo [...] [D] onCurrentItemChanged:155 - currentItem just changed to : Bar [D] onCurrentIndexChanged:151 - currentIndex just changed to : 2 [D] onValueChanged:159 - value just changed to : Bar 2. Then I tried to set currentIndex. There, for some reason that I don't explain, it seems that the ComboBox always resets : Component { // Some other stuff here ComboBox { id: project label: qsTr(Project) menu: ContextMenu { MenuItem { text: qsTr(Not set) } Repeater { model: ProjectsModel { id: projects } delegate: MenuItem { text: model.value } } } onCurrentIndexChanged: { console.log(currentIndex just changed to : , currentIndex); } onCurrentItemChanged: { console.log(currentItem just changed to : , currentItem.text); } onValueChanged: { console.log(value just changed to : , value); } } Component.onCompleted: { // Here I get the task object from the database. var task = Storage.getTask(id); if(task !== null) { for(var i=0 ; iprojects.count ; i++) { if(task.project === projects.get(i).value) { project.currentIndex = i + 1; // We have to +1 because of the Not set MenuItem. break; } } } } } And the output : [D] onCurrentIndexChanged:151 - currentIndex just changed to : 2 [D] onCurrentIndexChanged:151 - currentIndex just changed to : 0 I also noticed that, in this case, it reverts to 0 because I have a hardcoded MenuItem at index 0. If I remove the first hardcoded Not set MenuItem, ComboBox.currentIndex reverts to -1. If I have only hardcoded MenuItems, it works as expected. By the way, I think it could be great for the ComboBox to behave like HTML’s select : MenuItem could have a text and a value property. Setting a ComboBox value would automatically update currentItem and currentIndex. Something like this : ComboBox { menu: ContextMenu { MenuItem { text: qsTr(Some item) value: some_item } MenuItem { text: qsTr(Another item) value: another_item } } Component.onCompleted: { value = another_item; // This would highlight the second item, set currentIndex to 1 and currentItem accordingly. } } Of course, one could still set currentIndex or currentItem, and it would update everything accordingly. I'd be glad to work on this if you agree :) Thanks for your attention. My best wishes, -- François ___ SailfishOS.org Devel mailing list To unsubscribe, please send a mail to devel-unsubscr...@lists.sailfishos.org