I'm still trying to do some pretty basic stuff with qt, and it's been a struggle. I'm specifically targeting for Mac. My current problem is getting the forms to not suck.
The simple problem. Create a new MainWindow app. Go into the Qt Creator (open Forms -> mainwindow.ui).
Drag 3 labels into place. Then I dragged 2 Line Edits and for fun, a Dial, but that part probably doesn't matter.
Click the main window and then tell it to use Form Layout. Within Qt Creator if I resize the window, my various line edits expand to fill the available space, exactly like I want.
Run the app. All the line edit fields are a fixed length, very short (if I don't override their minimum width), and do NOT resize as I resize the window.
Three quarters of the reason to use Form Layout is for resizing capability.
I've tried clicking on the central widget before setting to Form Layout: no change in behavior.
I do get reasonable behavior if I use a grid layout, although I have to add a vertical spacer at the bottom or my dial resizes crazily as I play with the window size.
So... Am I just doing something wrong with Form Layout? Or does it not work well on Mac and I should use Grid Layout instead?
I really miss Motif's XmFormLayout. It took time to set all the constraints, but I could make my forms do exactly what I wanted. Ah, but so 1990s.
On the panel to the right where you can see the objects, click the centralWidget. In the property panel, scroll down until you get to the layout properties of the form layout. Set the layoutFieldGrowthPolicy to ExpandingFieldsGrow.
By default, the line edits are not growing to fill the available space on macOS because they are not supposed to. This is some sort of macOS UI guideline. QFormLayout follows the platform conventions by default.
It would also be nice if I can figure out how to NOT necessarily expand everything to full width. I have a few Line Edit widgets that I'd like to keep short. They're going to hold TCP port numbers.
For those, set the Horizontal Policy property (it's grouped inside the sizePolicy property group in the properties panel) of the affected line edits to something suitable. In this case, probably to Fixed, but look up the documentation first of what each setting does.
Related
I'm developing a Qt application and it's currently in an internal beta test. One member of the company has Windows configured to display text larger than its normal size, which breaks my UI. The About page, for example, currently looks like this:
but under his settings, looks like this (note the clipped text):
Coming from a C#/Winforms background, I'm amazed that I can't seem to find some easily configurable label property such as Form.AutoSize that will automatically size the labels to fit their containing text. I've tried messing with sizePolicy, scaledContents, and a few other properties, but none seem to do this.
I've come across various threads (such as this one) which give instructions for scaling the text to the label, but I want to do the opposite - scale the label to the text to facilitate for those with enlarged text settings like my co-worker. Is there a straightforward way to do this?
There are at least three solutions to this problem.
Use layouts. Their contents are scaled according to the size of the window.
Make a code which is executed whenever window size is changed. In that code, you get the width of the longest text in the window (How?)(another way) and then set window wider than that.
Do the same as in solution #2, but execute the code only when the dialog is shown. After that, alter the window properties so that its size cannot be changed.
I've been playing around with QtDesigner for some time now, but I can't find a real solution for my desired layout.
Here's what I'm aiming for, kind of an Eclipse RCP-like layout:
Five drag&dropable widgets which can be rearranged and whatnot (so Dockwidgets). Thats what happend in above screenshot, I just pulled five Dockwidgets into the Mainwindow and populated them with Items. But the problem is that Dockwidgets only snap to the edges of the Mainwindow, and leave space to CentralWidget, which you see in the middle. Is there some way to add a containing widget to the center and fill it with DockWidgets?
On a side note: Is it feasable to do something like this in the Designer? I see why this program is useful, as GUIs can be set up and changed extremly fast, but I feel like stripped of any power on the exact look. I'm kinda itching to (attempt to) write the GUI by hand, because I'm feeling so powerless! :-)
P.S.:How can the screenshot be scaled? It seems overly huge
Unfortunately no. As it says in the documentation
Dock windows are secondary windows placed in the dock widget area around the central widget in a QMainWindow.
I'm having all sorts of size problems with Qt. I am creating my own widgets and using different layouts (generally, I need my own to make them work properly without spending hours on the "powerful" default layouts... which don't lay things out as intended.)
Once I'm done with a widget and its layout though, it doesn't work right. The size is never getting set properly unless I call widget->resize(1, 1); which finally forces a "resize" and makes the widget look correct (i.e. recompute the geometry.) Even the updateGeometry() call has no effect.
This is a dreadful problem when the resize() needs to be called on the parent widget (yuck!) and from what I'm reading should not be necessary were the layouts properly programmed.
Is there a sample that works and is not several thousand of lines long, or does Qt require several thousand lines to make anything work perfectly, even the simplest widget?
What are the minimal functions to be called to make a widget & its layout work at once?
Thank you.
Alexis
P.S. I tried to implement the sizeHint(), minimumSize(), maximumSize(), others that I'm missing? I was hoping that would be enough. Obviously, I also implement the setGeometry() on the layout to resize the children appropriately.
--- addition 1
There is a sample image with a layout that clearly isn't available as is in Qt. The positioning, functions, and colors of the different keys is XML driven and works for any keyboard in the world.
(note, this sample doesn't show the Enter key displayed on two rows and wider below than at the top; more or less, not doable at all with the regular layouts; of course, it works with my version.)
--- clarification
I'm not too sure how to describe the problem better. I was thinking to write a test widget next to see how I can reproduce the problem and then post that and eventually fix it. 8-)
The default layout function that the internal Qt layouts make use of require a lot of coding. I would like to avoid having to copy/paste all of that because for maintenance, it makes it close to impossible.
--- today's findings
As I needed to tweak one of the widgets, I decided to add a VBoxLayout and make it work.
I actually found the problem... One of the widgets in my tree is a QScrollArea and that sizeHint() returns (-1, -1). Not exactly what I'd expect but... whatever you put inside that widget has better know how to compute its width and height or else... it fails.
Looking at the code closely, I could actually compute the width by using the widest width found. Once I used that, the widget would appear (and it actually resizes itself as things change in the list, kinda cool.)
This being said, my earlier comment about having a tree of widgets that auto-resize themselves stands. From the root up to the parents of the leaves in your tree, all of those widgets will need a valid layout. Once I added one in the top widget it resized itself and its children properly (well... in my case up to the QScrollArea, the rest required a bottom to top resizing. Funny how that works!)
--- ah! ha! moment (or: what you find reading the implementation code!)
Today I bumped in another problem which just needed the correct call... I just couldn't find anything worth it in the documentation.
All the objects have a layout now, but a certain parent would not resize properly. Plain simple.
I had a call to the parent as following:
// changes to the children are changing the geometry
parentWidget()->updateGeometry();
Yeah. The docs says that's what you have to do. Nothing happens at all with that call. No idea what it's supposed to do, I did not look at that function. It never did anything for me anyway.
So... I looked at the layout to try to understand how it would send the info up/down. I did not see much except for one interesting comment:
// will trigger resize
This is said of the SetFixedSize mode. To reach that function you need to make the layout for update. Ah! Yes... the layout, not the parent widget... let's try that instead:
parentWidget()->layout()->update();
And voila! It resizes correctly in all cases I have. Quite incredible that the widget updateGeometry() doesn't trigger the same effect...
Although it's possible to do what you want it sounds like the problems you are having are because you're using Qt in a way that it's not meant to be used. Why do you need separate widgets for each key represented on the keyboard?
I see two options, both of which are better in some way:
Use QGraphicsScene and QGraphicsView.
A single custom widget that uses custom drawing to display the keyboard (and likely uses hover for hints).
The first option is probably better. Your keys could then be represented by QGraphicsSimpleTextItem's or even a QGraphicsSvgItem. It also provides a number of standard layouts or you could choose to write your own layout. By default you can use the keyPressEvent or mouseReleaseEvent to respond to user interactions.
I'd highly recommend you take a look at the QGraphicsView examples to get an idea what you can do.
If you go the second route you'll need to record the different key locations so you can respond accordingly as the user moves the mouse around, clicks, etc.
This won't help you with your immediate issue but I wanted to show you a keyboard I made using standard layouts and buttons. It's not perfect and it still won't help you with an enter key that spans two rows but it's not bad. It's resizable too by resizing the window, although I'm not sure if that will be apparent from the images below as SO may be scaling them. (you can view the actual images by opening them in their own tab)
Anyway, this was done using only Qt Designer with no manual coding. It consists of a top level vertical layout with 5 horizontal layouts in it. The buttons are then inserted into one of the 5 horizontal layouts. The size of the keys can be controlled by setting the horizontal and vertical size policies to "ignored" for most of the buttons and then horizontal "minimum" for buttons that you want to be wider. Things can be tweaked by setting min and max size restrictions to buttons. When resized, the buttons will not maintain their relative proportions though, that would probably take some custom programming.
The styling in your example could be approximated pretty well using css style sheets and background images. Still not a minor effort but you should be able to get most of the way there without custom layouts and buttons.
I want to divide the application screen into parts like one part is fixed showing fixed controls & another one is variable which can be changed when user select something. Like in Qt Creator we are having the left side column always fixed & the content of center screen is changing when user is selecting something. I have attached the screen shot. How to do it. if any one is having any idea please help me.
When you speak of the Qt Creator you certainly mean the controls on the left and right. In my opinion, the best thing to implement that are QDockWidgets. Have a look at them in the docs and as Martin said, look at the examples, they are perfect to learn each of the layout and composing issues.
QDockWidgets can be made floatable (undock them from the main window as toolboxes), they can have fixed sides to be docked on and it's easy to use them, because they can be filled with every widget you like. I often use them when I show a file explorer in an application, for example. Just look at the examples and play with it.
If you just want to have QActions visible all the time for the user, you can use a QToolBar.
You normally start with a QMainWindow and then put other toolbars, controls, widgets etc inside that.
Check out the Qt examples that come with the SDK src
I have an MFC application. When running it on Windows 7 I realized that when changing the display percentage to meduium - 125%, I have a TextControl which is cut off (end of sentence doesn't appear.)
How can I fix this?
I could enlarge the size of the control on the dialog, but I'd rather do that via the code.
My application is localized and I woudn't want to change all the dialogs on every language.
In general, the issue is that absolute coordinates are being used for some sizing rather than relative. The framework will initially lay things out correctly in large DPI, it's then up to you to keep things straight through resizes.
You can use a layout framework like this one: Ultimate Toolbox Layout Manager, or you can roll your own.
Here's a common pattern I use:
Define a struct that captures ID, size, location, and layout behavior (anchor top|left|right|bottom) of a control
In the document constructor initialize an array of structs with your desired layout behavior
In OnInitDialog, capture the initial control positions, e.g. for controls set to anchor top left you need to grab the initial distance from the top and left of the parent.
In OnSize, reposition and resize each control according to its layout behavior.
I'm not exactly sure if it helps in your case but the ResizableLib works pretty well for me. You can also skip creating a library and just use the files in your project.
There is a separate article for CResizableDialog which explains in a few easy steps how to implement this for existing dialogs.