Implementing a QtDesigner-like behavior with QtDesigner - qt

I want to implement an editing procedure like the one seen in QtDesigner. That is, having a toolbox of available "blocks" and being able to drag them into the working area of program to create a new instance of some sort of editable object (or widget).
I know that I can write it from scratch, but it seems logical that you can create something like QtDesigner within QtDesigner. I noticed that for toolbox they used a combination of Dock Widget and List Widget.
But I struggle to come up with the correct elements for the drag & create behavior.

Related

What is the best way to implement this using Qt

I'm totally new to Qt, so I'd be glad to have a wide answer.
Here I drew up some model:
We have a kind of table that contains:
an integer value with a spinbox.
a cell with three(not specifically) grouped radio buttons
Editbox
A button that interacts with this particular editbox.
Also we have 2 buttons to add and remove items from the table.
I did some google search and found out that it can be done via QTableView.
Is there any way to put such complex structures into a cell? Must it be a separate class inherited from QTableView?
If you're going to have up to a hundred or maybe a few hundreds of elements in the table, then use QTableWidget.
If you're going to have too many elements (about thousands), then go for QTableView, and learn model-view programming.
The reason why I recommend QTableWidget is because you're a beginner. All you have to do there is create a widget, and use setCellWidget() and you're done.
If you have thousands of rows, then you're gonna have to draw the widgets yourself using QStyledItemDelegate, which will paint the widgets inside your QTableView. This is a very painful thing to do, but there's no way around it. The reasons you can find here.
I see at least three options to implement that in Qt:
Use a QtableView or QTableWidget and insert some custom controls in it. See comments made be other persons to your post
Use a QGridLayout and fill it with your controls by line and column
Make your own QWidget to store and manage the line elements (the spinbox, edit field, radio button) using a QHBoxLayout. You can design this in QtCreator, it can have it's own .ui. This could make it easy to handle the interaction between each QWidget of a line (directly handled by your QWidget class). Later, you can put an instance of it for every line you need in a QVBoxLayout.
Personnaly, I would go with the last option, but it may not work smartly if the controls of each line have different content/size (see comments), then first options should be prefered.

How to implement a tree view like the visual studio solution explorer with Qt?

I want to implement a tree view like the visual studio solution explorer with Qt. The tree is used to represent an external data called "project". I want to use Qt model/view architecture.
(1) QTreeView for the view, and the model is derived from QAbstractItemModel which include a pointer pointing to the project object.
(2) The items under a directory are sorted by its name. When adding an item under a directory, it will automatically be put on the right position.
(3) When double clicking an item in the tree, a dialog will pop up for editing.
Any good ways to implement the (2) and (3). Thanks a lot!
Ad 2) Taking a look here might be helpful: http://doc.qt.digia.com/qt/qsortfilterproxymodel.html. It contains examples of implementing a more complex sorting and filtering of the items.
Ad 3) Overrride QTreeView::mouseDoubleClickEvent().
Just a side note, as an alternative, you could use QTreeWidget and QTreeWidgetItem, in which case you might want to traverse the tree and insert child items directly at the position you want.

Qt custom widgets with custom items - Qt Designer/ uic

I have started working with Qt again. What we want to do is to automatically generate graphical user interfaces. Therefore I have taken a closer look at the .ui file format (which is a XML based file format). These files are generated by the Qt Designer but can be easily be created by any other software. This part works so far.
But: we want to add some custom widgets. Creating custom widgets is also not that difficult. Some good websites exist out there: Creating Custom Widgets for Qt Designer, Using Custom Widgets with Qt Designer, (more hyperlinks held back),...
My question is rather: how can you implement custom widgets displaying custom items. Let's take one example. We have a QComboBox and a QSpinBox. The combobox has three items
A
B
C.
When selecting "A" I want the spinbox' minimum set to 1, maxiumum set to 9; when selecting "B" the spinbox' minimum should be set to 10, and its' maximum to 99; selecting "C" should set the spinbox' minimum to 100 and the maximum to 999. How is this done properly?
At the moment I set the data in a QTableWidget which is a helper class for me. Each row has three columns/cells:
item | min | max
-----+------+-----
A | 0 | 9
B | 10 | 99
C | 100 | 999
And I have my custom widget which contains the QComboBox and the QSpinBox. At runtime I tell the custom widget to take data/model from the QTableWidget and copy to itself by a method called setFriendContainer() [it's even a public slot which should be connected to a signal from the tablewidget which is emitted automatically]. Afterwards the tablewidget is not needed any more! I don't even want to show it to the user at all (this is why some size properties are set to 0; but it's partly still visible).
I think this is not really a clean way to implement it. What would be better/ an alternative? The items are also generated and should be contained in the same .ui file. Of course it would be possible to load it at runtime from another file, but I think this isn't rather an option. Do you think my workaround is ok, or is it too "ugly"? There are some examples where you can see how to add single custom properties, but I think this is something different - if you want to add whole containers (lists or tables of items, whatever). But including it in the .ui files might even be against the whole model/view concept?!
Any help welcome!
Thanks,
Matthias
I have added our data in a custom property in the form of XML. The data stores some coding information used in the widget. It's good to have the dynamic properties.
Remember that you are dealing with the properties of the widget. A UI file is nothing more than a description of the widgets, their properties, and their relation to each other in the hierarchy. A custom widget is no different than something like a QPushButton or QComboBox to Designer. The important thing is to encode the properties of your custom widget in a way that is understandable in the UI file.
You probably are best served by looking at the UI schema and making sure your widget can be described in a valid file. After that it's just to make sure that your properties behave correctly (i.e., that you can set properties in any order and get the same result). How you implement the widget is really up to you (make your own data structure, don't drag an "invisible" tree widget in).

Drag and drop of QDockWidget between two or more windows

I would like to know if anybody knows if it is possible to drag a QDockWidget from one window to another.
I am developping an application that has a lot of windows. Each of these windows has a specific usage. I want to use QDockWidget because of the automatic rescaling when docking a widget in the main window. But I would also like to have the possibility to have a new dock area in a new window so that I can put together all the widgets related one to each other.
Does anyone have a suggestion?
As far as I know, you cannot drag a QDockWidget from one application to another if they are developed separately.
On the other hand, I think that you can reparent a QDockWidget to another QMainWindow, only if it's part of the same application.
...aaaaand you can always try to intercept the drap/drop events and pass information between the two windows with a protocol of your own: define a new mime type for the drag and define the syntax of the data associated to the QDockWidget. Then, implement the code to analyze the data and reconstruct the contents of the QDockWidget in the target window... not an easy task!

How do I tell Qt to always show an editor in a QTableView?

I've got a QTableView for which I want to display the last column always in edit mode. (It's a QComboBox where the user should be able to always change the value.)
I think I've seen the solution in the Qt documentation, but I can't find it anymore. Is there a simple way of doing it?
I think I could archive this effect by using openPersistentEditor() for every cell, but I'm looking for a better way. (Like specifying it only one time for the whole column.)
One way to get the automatic editing behaviour is to call the view's setEditTriggers() function with the QAbstractItemView::AllEditTriggers value.
To display the contents of a given column in a certain way, take a look at QAbstractItemView::setItemDelegateForColumn(). This will let you specify a custom delegate just for those items that need it. However, it won't automatically create an editor widget for each of them (there could in principle be thousands of them), but you could use the delegate to render each item in a way that makes it look like an editor widget.
There are two possibilities:
Using setIndexWidget, but Trolltech writes:
This function should only be used to
display static content within the
visible area corresponding to an item
of data. If you want to display custom
dynamic content or implement a custom
editor widget, subclass QItemDelegate
instead.
(And it breaks the Model/View pattern…)
Or using a delegate's paint method. But here you have to implement everything like enabled/disabled elements yourself.
The QAbstractItemModel::flags virtual function is called to test if an item is editable (see Qt::ItemIsEditable). Take a look at Making the Model Editable in the Model/View Programming documentation.
I can't see an easy way to do this, but you might be able to manage by using a delegate. I honestly don't know exactly how it would work, but you should be able to get something working if you try hard enough. If you get a proper delegate, you should be able to set it on a whole view, one cell of a view, or just a column or row.

Resources