1

I am writing gui application. I want to implement following structure:

  1. project tree with nodes of different type and behavior (i.e. when right clicking or selecting there can be different menu options)

  2. Editor window, which can be dynamically splitted vertically and horisontally, to add more edit areas. Each edit area corresponds to one node of project tree.

I am using c++/qt, but have the problem in design rather than programming languages and libraries.

Currently, to implement project tree I created abstract interface of tree node which contains link to parent and to children. For each node of specific type I make new class. Because I am using Qt, I have a model, which acts like a intermediate object between view and actual tree. It seems correct that information from visual representaion can't leak to this tree.

I have the following problems with implementation:

  1. Is it right to use this tree as a holder of all my data? Can I use it to hold information about objects I'm editing, or should I use external holder for all data, but have link to it from my nodes?

    1. In case of holding information about objects, the information about visual representation, already passed to objects (they know structure of the tree).
    2. In case of link to external holder, I can't understand how to create such link and support dynamic creation/deletion of nodes.
  2. When I click on view item, I want somehow to make data inside node to be opened for editing in selected edit area.

    1. I can't figure out how to do it without dynamic_cast'ing to specific type of node and passing that internal information to currently selected edit area.
    2. Another badly looking approach, which come to my mind is to introduce virtual function in node, but node can't implement the logic of this function, because it relates to visual representation.

Example of tree:

Models is entities which can be edited by own vector graphics editor, Materials is table-like key-value properties, where each key can be attached to some primitives in graphics editor.

  • I'm not familar with QT but in other GUIs, what you're implementing is often called a treebook. It's like a notebook but uses a tree instead of index-card tabs. – shawnhcorey Feb 20 '18 at 12:45
  • 1
    This is hard to answer without a notion of what kind of data you application manages. Is a tree the most natural represenation of that data, or is it just a specific view? – Doc Brown Feb 20 '18 at 13:00
  • @doc-brown For example, it can be editable tables (like that in office apps) inside nodes or editor to paint some geometry primitives (like paint). – Bhavin Chirag Feb 20 '18 at 13:03
  • @shawnhcorey Yes, It is very similar to wxTreebook from wxwidgets. I think there is no alternatives in QT, so I try to figure out how to implement it by myself. – Bhavin Chirag Feb 20 '18 at 13:08
  • @doc-brown I think tree is the most easiest way to interact with those primitives for user, but the data itself is totally independent on tree structure. As I stated it is a project tree, where each project contains some data and can be saved/loaded. – Bhavin Chirag Feb 20 '18 at 13:14
2

If that data itself is mostly independent of the tree structure, it is probably best to have a clear separation between UI and data. So the answer to your first question

should I use external holder for all data, but have link to it from my nodes

is IMHO clearly "yes, absolutely". You should hold your data in some UI independent object model or repository and have each node (which I interpret as part of the UI) hold a link/pointer/smart pointer to the related object. If you currently don't know how to create or manage such links, you have to dive deeper into the Qt docs, or consult Google. I am not an expert on Qt, but I guess you need to derive a special subclass of the QStandardItem which can hold such a link/smart pointer to the object (or whatever Qt object represents the tree nodes in the UI). Maybe this older SO post can help you.

For your editing problem, the class representing the UI nodes could also hold a second link to the correct editor object. So it will be easy to implement a method in that subclass which calls the correct editor for the related data without dynamic casting. The place where you have to pair the correct editor with the corresponding data object then is the place where your tree node items are constructed.

  • Thank you for response! For the first problem, if I store data outside the tree then where exactly (I am asking about general principle, but not about Qt details)? For the second problem, it seems absolutely wrong to store link to editor, because model/data shouldn't know anything about view/representation (for example some models can be opened twice, some can be not shown). I need some clarification. – Bhavin Chirag Feb 20 '18 at 16:47
  • @BhavinChirag: 1) this depends somewhat to the overall architecture of your application, where the data is coming from (some database? Some global document/dataset inside of your application), if there is some ORM in use. Don't think I can easily answer this in two sentences. – Doc Brown Feb 20 '18 at 19:17
  • 2) As I said, I am not a Qt expert, a look into the docs gave me the impression the QStandardItem represents the items within the tree view and though they belong more to the UI layer (being part of a view model, not of the data model). Maybe I got this wrong, you better try to find an Qt expert on stackoverflow about this particular detail. And yes, your data objects themselves should know nothing about any editor. – Doc Brown Feb 20 '18 at 19:19
1

The general answer to "My GUI library doesn't contain a component that meets all my needs" is to combine a collection of GUI elements that together do what you want. If you find yourself needing this in multiple places, you can package it up as a new component. Only very few GUI elements are entirely coded from scratch, e.g. consider how a combo-box is implemented: it is a button, a line edit, a popup menu and some connections.

In this case, you can have a tree view (QTreeView or QTreeWidget) for selecting which data to present, and multiple frames for showing a view on a specific datum (QStackedWidget or QMDIArea).

The data on the tree node then only needs to identify the data to be drawn. When the selection changes, the relevant frame on the stack is activated, and then populated from your data source

  • Thank you for response, but I think you answer slightly different question. – Bhavin Chirag Feb 20 '18 at 17:21
  • "It is very similar to wxTreebook from wxwidgets" - this is a general outline of how to do that. Have a look at item selection models – Caleth Feb 20 '18 at 17:39
1

Personally, I think the tree view is not the right tool for this job, if I've understood your document model correctly. It seems like your "Materials" are similar to styles for text in a word processor. It seems like the "Models" are the meat of what the user wants to work with, and that they apply materials to the models, just like styles are applied to words in a word processor. I've never seen a word processor where the pages were shown in the same tree structure with the styles, for example.

So I would consider modeling your data in a similar way. I would have a document object. The document would have a list of Materials, each of which has an ID that is not its index in the list. I would then have a completely separate list of models in the document, and the models would refer to the materials by their ID. By dissociating the material's ID from it's position in the list, if the user adds a new one between 2 existing ones, you don't have to update every model that uses the later materials.

I would then have separate UI for listing the models and the materials in a given document. For example, in Microsoft Word, there is a pop-up menu containing all the text styles you can apply, and an option to create new ones or edit existing ones. Whether that's the exact UI you need here is debatable, but some way of separating them makes sense to me. If your materials are hierarchical (such as material B inherits all material A's properties and adds some new ones), then a tree view would be appropriate just for the materials. If not, then some sort of list is appropriate - either a list, a table, a pop-up menu, a combo box, or whatever.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.