In my project I going to generate a user interface through programming. Scalability of this UI is very important requirement.
So far I am using two dimensional graphics for generating the UI.
I think there may be different solutions but for the moment I know only two.
First one is supplying X,Y coordinates of each two dimensional graphic on my UI.(I do not prefer this solution because I do not want to calculate X,Y coordinates of each graphic. For the moment I don't have a logic for doing this easily)
Second one (which is currently I am using now) is using layouts which organizes its contents according to size of item. In this solution I don't have to calculate X,Y coordinates of each item. (Layout is doing this for me.) But this approach may have its own pitfalls.
I am very new to user interface programming. Can you give me advice about this issue?
The general rule I follow is that you should always use layout containers unless you have very specific reasons to use an absolute layout. The only real times I use absolute layouts is when I'm implementing a weird custom layout that doesn't fit easily with built in layout managers.
Layout managers will make your life much easier. Handling resizing windows or variably sized content is made significantly easier with layout managers.
I can't remember every having a problem with qt's built in layout stuff.
I am assuming you rail map only needs to be a schematic of the real track layout, you could create components that are all layed out on a grid, and for each grid cell you implement a simple layout algorithm, depending on your requirements you could just state that one grid cell can only have one actual control on it (and make the cells smaller) or for larger cells you have fixed spots for each type of control, or just arrange the controls within a cell from left to right/top to bottom, whatever works for you. You could also subdivide the cells themselves into subcells to constrain the controls. So that when you scale the whole, each cell can then tell the control what size it should be.
It might also help to implement things as layers on your display, for example make the track layer separate from the control layer.
You are working on a very specific "non-traditional" ui you will need some solutions that fit your problem.
I don't know if you are doing this already, but think if you can implement a data driven approach for the configuration of your UI. Don't hardcode the layout, separate the layout functionality from the actual operational parts and move them into a file that can easily be changed.
It sounds you have some kind of working solution but you said "I do not prefer this solution because I do not want to calculate X,Y coordinates of each graphic", if you have graphical controls that can be placed anywhere on the screen though code, it is probably not a big step to have an editor where a user can place these controls. It might not be as much effort as you think, especially if you are already using a configuration file for your UI instead of hardcoded values.
I have recently done a lot of work changing the normal look of qt elements through styles, but I don't think that the normal qt-gui parts will be enough for your endeavor, but the QGraphicsView subsytem would probably be a good fit it does scales well and handle interactions with large number of elements well, but it is hard to give you a more specific answer without knowing more details
There is Qt Designer (GUI Builder) which allows designing GUI like in Visual Studio.
Calculating X,Y by hand is a bad approach - it is absolutely inscalable.
Don't reinvent the wheel:
Inherit your objects from UI objects e.g. panels so you could use the UI techniques from those objects.
For the rest use containers or any other layout objects
Related
I am moving an application of mine from an old GUI (where I used fixed sizes) to wxWidgets (where I am trying to learn the basis of sizers).
Inside the application I have several forms with quite complex structure. Nature of data and workflow suggest me to keep all these data together in a single screen.
But this screen has to be properly designed be usable.
Here's the old version of the form ...
... and here's more or less what I could come up with using sizers ...
Please note that I could not simply use a wxGridSizer, since some of the widgets span throughout the row, some other get out of the fixed grid etc.
Obviously I could keep working on it to make it less ugly, but I found myself thinking maybe sizers are not the correct tool to do it. To achieve what I want I would need something similar to wxGridSizer with some sort of colspan/rowspan mechanism, and maybe that wouldn't be enough.
So I started thinking to build a "Form Sizer" by myself that could go something like
int w,h;
GetClientSize(&w,&h);
MyFormSizer *formSizer(w,h);
formSizer->SetDimension( widget1, 100, 20 );
formSizer->SetDimension( widget2, 500, 20 );
formSizer->newRow();
formSizer->SetDimension( widget3, 100, 20 );
formSizer->SetDimension( widget4, 250, 20 );
formSizer->SetDimension( widget5, 250, 20 );
formSizer->Layout();
The user would set the relative sizes of every widget, to block the geometry of the form completely. To make this geometry fit the wxPanel when resizing Layout() would calculate an appropriate scaling factor f and then would set all sizes and positions doing something like
widget1->SetSize(CalculatedX, CalculatedY, 100/f, 20/f);
CalculatedX+=100/f;
widget2->SetSize(CalculatedX, CalculatedY, 500/f, 20/f);
CalculatedX+=0;
CalculatedY+=20/f;
and so on (this is just a scratch, take it as the rough idea; there should be mechanisms to avoid making everything too small to fit the text in the widgets and/or to scale the font size accordingly and such stuff).
Does it seem reasonable? How would you face the topic? This choice is going to affect quite a bit of my future developing, so any answer, criticism and comment will be very welcome
wxGridSizer might not fulfil your needs but more flexible classes such as wxGridBagSizer should do what you want. This class allows you to set items to span multiple rows and columns by setting wxGBSpan when calling wxGridBagSizer::Add.
As mentioned in #sjdowling's answer, you could use wxGridBagSizer. However I don't recommend using this class as it suffers from some problems of the absolute positioning, notably it makes it very difficult to move elements around it or to add them except at the very end.
It's true that wxWidgets sizers lack the ability to align elements across different sizes, which is what you'd need here if you used normal box or grid sizers and this is annoying. However you can work around it by fixing the sizes of the columns explicitly, either by just hard-coding them (please at least use dialog units and not pixels though to avoid broken layouts, especially in high DPI situations), or by iterating over all the labels and calling GetTextExtent() on all of them and choosing the longest one (this is much more reliable, especially when using translations which can drastically change the width of the string in pixels). Then simply assign this width to the labels you create: as the initial width is also the minimal width, this will ensure that all of them have this width and so are aligned, even if they are in different sizers.
As I wrote, this is somewhat annoying but really not that bad if you're creating the layout in the code. If you do it in a GUI designer, it's even uglier, but you can still call wxSizer::SetItemMinSize() from the code. Of course, the only real solution would be to add support for inter-sizer alignment, but for now this is still preferable to using wxGridBagSizer IMO.
I am designing a GUI in Qt that has placeholders for a number of images (images will be set and updated at run time) along with some input fields (QLineEdits with QLabels grouped into QGroupBoxes). I am using a technique similar to the answer here:
How do I make an image resize to scale in Qt?
for the image display widgets. Some are a class that inherits from QWidget that can draw an aspect-scaled image, others are a class that inherits from QLabel that can do the same and also display text. These are custom C++ classes.
The problem I am having is with the layout and getting things spaced correctly. I am using Qt Designer to layout the GUI. Since the image widgets are "empty" they don't exert a lot of "force" on the other widgets and the other widgets tend to dominate even though I don't need the other widgets to be that big. The QLineEdits especially like to be as wide as they can be. I want to GUI to be adaptable for different sizes (to accommodate different screen resolutions) so I don't really want to set a lot of sizes manually if I can help it.
I do not have a lot of experience in Qt and managing layouts. What I know I have mostly learned from playing around with it. I have tried searching for similar situations without much success. I can't figure out the terms to use for my specific situation. Does anyone have any suggestions for what I can do to better control the layout? Alternatively, are there any good resources for learning how to manage Qt's layouts? The Qt documentation I have looked at is fairly basic. There are a lot of options, most of which I am unsure exactly how they should work, and the trial-and-error approach is getting to be too cumbersome for more complex layouts.
I am using Qt 4.8.
Sorry to be vague. This is a work project and I would rather not post exactly what I have. And coming up with a generic example will take time. I think my questions are generic enough that it shouldn't matter. If a more specific example is needed, I can try to throw something together.
Edit:
Here is what the layout looks like in Designer right now. The black boxes are redacted labels. The orange boxes are where images will go. The one in the top-left corner is a particular problem. I currently have the top and bottom halves on the left in a splitter in an effort to make things fit better. I think that may be making it worse.
http://i.stack.imgur.com/nRRg3.png (long-time reader, first-time poster :-/)
Making the "What I want it to look like" picture is going to take a bit longer. It may be easy to see what I don't like. The input fields need to be much smaller to make room for the images.
Edit2:
And here's something closer to what I would like. The upper-left and right-hand images are larger and actually visible. I might like the boxes in the lower-middle to be even bigger, but there's only so much room. If I can get the layout right, I'm hoping that will optimize the size of everything for a given window size.
http://i.stack.imgur.com/yvLvi.png
I am building an editor using C++/Qt which has a click-and-drag feel to it. The behavour is similar to schematic editors (Eagle, KiCAD, etc), Microsoft Visio, or other programs where you drag objects from a toolbar into a central editing area.
My problem is that when the user clicks inside the custom widget I want to be able to select the instance of the box-like object and manipulate it. There will also be lines connecting the boxes together. However, I can't decide on an efficient method for selecting those objects.
I have two main thoughts on how to do the programming for this: The first is that the widget which is drawing the entire editor would simply encapsulate every one of the instances of the box. The other is to have each instance of the box (which is in my Model) carry with it an instance of a QWidget which would handle rendering the box (which would be in my View...but it would end up being strongly attached to the model). As for the lines connecting them, since they don't have a square bounding boxes they will have to be rendered by the containing widget.
So here is the summary of how I see this being done:
The editor widget turns into a container which holds the widgets and the widgets process their own click events. The potential issues here are that I don't know how to make the custom widget turn into a layout which lets click-and-drag functionality.
The editor widget takes care of all the rendering and processes the mouse clicks (the easier way in that I don't have to worry about layout...its just selecting the instances efficiently that I don't know what would be best).
So, now that there is a bit of background, for the 2nd method I plan on having each box-like instance having a bounding rectangle and the lines being represented by 3-4 pixel wide bounding rectangle segments (they are at 90 degree angles). I could iterate through every single box and line, but that seems really inefficient.
The big question: Is there some sort of data structure I can hold rectangles in and link them to widgets (or anything else for that matter) and then give it two coordinates (such as mouse coordinates) and have it spit me out the bounding box or linked object that those coordinates are inside of?
It sounds like your real question is about finding a good way to implement your editor, not the specifics of rectangle intersection performance.
You may be interested in Qt's "Diagram Scene" example project, which demonstrates the QGraphicsScene API. It sounds like a good fit for the scenario you describe. (The full source for the example ships with Qt.)
The best part is that you still don't have to implement hit testing yourself, because the API already provides what you are looking for (e.g., QGraphicsScene::itemAt()).
It's worth noting that internally, QGraphicsScene uses a simple iterative method to perform hit tests. As others have pointed out, this isn't going to be a serious bottleneck unless your scenes have a lot of individual items.
I'm using QT creator and have all my methods etc designed and trying to design a UI and I'm not sure what widget I should be using to reference my puzzle layout.
I've been reading over the documentation for a while and I still am nowhere closer to finding a solution to what I should be using to display my values. I know what I should like but all I seem to find information on is various layouts of entry boxes that are in no way linked. I have no problem with coding it myself to communicate with my classes if I just knew what to use to start off with.
I need something that can help me create a layout that has up to two numbers with positions specific to the type of hint it is with a slash between the hints, black blocks that are neither hints nor stored values and squares that have values that can take up the whole square.
Layout is something similar to http://www.nikoli.co.jp/en/puzzles/kakuro/
I wish I knew what to pick >.<
Personally I'd use QGraphicsView and handle the drawing myself.
It can draw rectangles, triangles, circles and text without much effort, and that's pretty much everything you need as far as I can see. You just need to add the objects to a QGraphicsScene and you get them on the screen. You can also interact with the objects (you can find which object you're pointing at etc.)
I have been working on a simple GUI and have hit a roadblock. I haven't found any examples or even readable source on how to create a GUI layout manager. I was wondering if anyone knew of some resources on creating one, or some source code that isn't cryptic like Qt's layout engine.
It depends on what you mean by "layout manager", and I'm not familiar with Qt, so that doesn't give me much of a clue.
If you mean things like resizable window handling, though, I think the relevant term is "constraint solver". I've never looked into it that much, but I believe GUI constraint solvers are based on linear programming - the Simplex algorithm and all that. It might be possible to do something with Gaussian Elimination, but I'm far from confident about that.
Based on a quick search for "gui layout linear programming", you might find this paper from CiteSeerX interesting - there's a PDF download. If you don't like cryptic, well, at a glance at least it's not exactly math heavy, but I suspect it's not light reading either. I guess I'll find out shortly, as you've got me interested.
I am currently making a Windows port for Mozilla XUL. My approach does not involve linear programming techniques like Steve mentioned, but it is a more object oriented approach. It is based on the Composite and Decorator design patterns.
The composite pattern allows you to create controls that have child controls, which in turn can have their own children. A control is responsible for positioning its child controls within its designated client rectangle.
For example suppose you want to implement a layout that positions its child controls horizontally. The layout algorithm then needs to calculate the width of each child control in order calculate the x offsets for each child control.
Calculating the width of a container is done by returning the sum of the widths of the child controls.
The Decorator classes can be used to add extra properties. For example a MarginDecorator can add spacing between child controls, a ScrollDecorator can scrollbars, etc...
It's a fun thing to do, I wish you good luck!