There is a label on Frame, I need to make its size taken into account even in hiden state! I can write explicitly from the code:
QSizePolicy spSomeLabel = mUi->SomeLabel->sizePolicy();
spSomeLabel.setRetainSizeWhenHidden(true);
mUi->SomeLabel->setSizePolicy(spSomeLabel);
But how do you do that from the ui markup itself?
Related
I am trying to make an app with live translation of text in a large tree model menu structure, in the same manner as: https://code.qt.io/cgit/qt/qtbase.git/tree/examples/widgets/itemviews/simpletreemodel?h=5.15
The item's "data" is a QString that is translated like
root = new MenuObject(tr("Main menu"));
And children are appended like:
root->appendChild(new MenuObject(tr("Test 1")))
.appendChild(new MenuObject(tr("Test 2")))
I am using QML to show these, with a qmllistpoprerty to show these menus like:
Q_PROPERTY(QQmlListProperty<MenuObject> list READ getList NOTIFY listChanged);
The QML is a simple ListView with a delegate Label showing the MenuObjects's description with the q_property:
Q_PROPERTY(QString description READ getDescription CONSTANT);
To change language i am using a function getting the translation file into the translator, followed by:
installTranslator(translator);
engine.retranslate();
Now this does work for simple q_properties like:
Q_PROPERTY(QString header READ getHeader NOTIFY listChanged);
Where
QString MainMenu::getHeader(){
return tr("Header");
}
But I CANNOT get the translations to work for the items in the treemodel. Any help is appreciated.
If your description prop never fires an updated signal, then your UI will never refresh it.
The reason it works for Q_PROPERTY(QString header READ getHeader NOTIFY listChanged); is because presumably the listChanged() signal is fired whenever header is supposed to change also.
To fix it, you need to declare an appropriate NOTIFY signal for your description, and of course it is no longer a CONSTANT.
I have been working for a little while now on creating a QT custom designer widget for GUI menus. The idea being that you simply drag it into the designer, select the number of frames you'd like, how many buttons per frame, etc. and it generates and sizes everything for you.
The way the widget is structured there are properties to configure each button for the frame you are in. For example, you would use the button0Text field to enter text under Button0 while editing in frame 0, then use it again to edit Button0 which is in frame 1. Both buttons would retain the individual changes for each frame.
The Problem
Normally when I switch frames all of my properties are updated to reflect the status of the frame. The exception being QIcon. The correct icon is retained in the actual graphical representation and builds correctly, however the file path in the property list is always of the last edited for that property. I think this will be extremely confusing to an end user and I have found no way to fix it. So for example, if I set text and icons in frame 0 then switch to frame 1 the text in the property list will update to reflect the state of frame 1 but the icon path names will still show my last edit in frame 0 and not the actual icon in frame 1.
I have tried things as simple as:
setProperty("button0Icon", getButton0Icon());
That code works on properties like text, but not for the icon. I try executing it immediately after changing frames.
I have also tried:
#ifndef Q_WS_QWS
QDesignerFormWindowInterface *form = QDesignerFormWindowInterface::findFormWindow(this);
if(form){
QDesignerFormEditorInterface *editor = form->core();
QExtensionManager *manager = editor->extensionManager();
QDesignerPropertySheetExtension *sheet;
sheet = qt_extension<QDesignerPropertySheetExtension*>(manager, this);
int propertyIndex = sheet->indexOf("button0Icon");
sheet->setChanged(propertyIndex, true);
sheet->setProperty(propertyIndex, getButton0Icon());
}
#endif
And:
int propertyIndex = this->metaObject()->indexOfProperty("button0Icon");
QMetaProperty property = this->metaObject()->property(propertyIndex);
property.write(this, QIcon());
Nothing seems to update the property list in the designer.
I have all properties, including all QIcon properties properly declared in the header file with Q_PROPERTY and assigned getter and setter functions.
To be clear, the icon values are indeed retained through each frame when compiled. So it is functioning, just unclear for most users.
If anyone has any experience with this or any ideas please let me know. Thanks.
I have discovered that QIcon does not store file names/paths. The file names are only used for the creation of the QIcon. I think this is most likely the reason I do not get any feedback in the Property Browser for my QIcon properties.
Instead I have chosen to hide this property in the designer and add three new ones. Three QUrl properties, each of which is used to supply an image file. I use three because I want to construct a QIcon that contains Modes/States for normal, disabled, and pressed operations.
I take each of these QUrls and save them in QStringLists behind the scenes so their values are stored. I then construct my QIcon using the file names provided from the QUrls.
I would much prefer to be using the native QIcon in the designer for this, any thoughts or feedback are appreciated.
The application that I'm building is supposed to create, destroy, and manipluate widgets that I've created
The problem is I'm not making a simple program with nice buttons where everything is symmetrical and needs to be evenly spaced and handled via a layout that will automatically move everything around and space it.
And yet, the only way I know of is to manually instance a layout and add the widgets to it, but then I can't set the coordinates of them
How can I simply instance my widget, and add it to the project generated frame?
This is how I'm instantiating my class, in which case I then set my own parameters:
Tile *tile = new Tile;
tile->setImg("://Images/placeholderTile.png");
tile->setCol(true);
tile->setGeometry(retX(line),retY(line),50,50);
To reiterate, I want to add my own widgets to a frame outside of the editor (only by code), and be able to manually move them around the frame by code.
I don't see an ".addWidget() as a method accessible from the QFrame, and yet they can be children within the designer, why can't I do this by code? Whenever I try to do it manually and add them to any layout, any attempt I make to manually set the widgets location doesn't do anything. I haven't overridden the setGeometry
I fixed my problem
After 2 hours of continual searching I finally came across my answer
I never thought that you could set the parent of a widget by code, as I thought you strictly had to add it in as a child of something else, not the reverse and declare that it should have a parent
So, by simply adding the line:
tile->setParent(ui->frame);
completely fixed my problem.
I will change this post back and submit the answer tomorrow when I'm allowed to by this site.
Thank you to those who actually came though. I'm just glad I managed to fix it before that.
All you need is to pass the parent to the widget's constructor:
Tile *tile = new Tile(ui->frame); // <-- here
tile->setImg("://Images/placeholderTile.png");
tile->setCol(true);
tile->setGeometry(retX(line),retY(line),50,50);
Since Tile is your own class, you should definitely have a Qt-style, parent-taking explicit constructor for it:
class Tile : public QWidget {
...
public:
explicit Tile(QWidget * parent = 0) : QWidget(parent) { ... }
};
Another approach is to write your own layout that would know about the relationships that are to be held between your objects. After you do it once, writing custom layouts isn't that hard.
I am using QT to create a chat messenger client. To display the list of online users, I'm using a QListWidget, as created like this:
listWidget = new QListWidget(horizontalLayoutWidget);
listWidget->setObjectName("userList");
QSizePolicy sizePolicy1(QSizePolicy::Preferred, QSizePolicy::Expanding);
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(0);
sizePolicy1.setHeightForWidth(listWidget->sizePolicy().hasHeightForWidth());
listWidget->setSizePolicy(sizePolicy1);
listWidget->setMinimumSize(QSize(30, 0));
listWidget->setMaximumSize(QSize(150, 16777215));
listWidget->setBaseSize(QSize(100, 0));
listWidget->setContextMenuPolicy(Qt::CustomContextMenu);
Users are shown by constantly refreshing the list, like this: (Note: There are different channels, with different userlists, so refreshing it is the most efficient thing to do, as far as I know.)
void FMessenger::refreshUserlist()
{
if (currentPanel == 0)
return;
listWidget = this->findChild<QListWidget *>(QString("userList"));
listWidget->clear();
QList<FCharacter*> charList = currentPanel->charList();
QListWidgetItem* charitem = 0;
FCharacter* character;
foreach(character, charList)
{
charitem = new QListWidgetItem(character->name());
// charitem->setIcon(QIcon(":/Images/status.png"));
listWidget->addItem(charitem);
}
}
This has always worked perfectly. The line that I commented out is the one I have problems with: my current goal is to be able to display a user's online status with an image, which represents whether they are busy, away, available, etc. Using setIcon() does absolutely nothing though, apparently; the items still show up as they used to, without icons.
I'm aware that this is probably not the way this function needs to be used, but I have found little documentation about it online, and absolutely no useful examples of implementations. My question is, can anybody help me with fixing this problem?
This is how you may conduct your debugging:
Try the constructor that has both icon and text as arguments.
Try to use that icon in another context to ensure it is displayable (construct a QIcon with same argument and use it elsewhere, e.g. QLabel!).
Use icon() from the QListWidgetItem to receive back the icon and then look at that QIcon.
Create a new QListWidget, change nothing, and ordinarily add some stock items in your MainWidget's constructor. See if the icons show up there.
I'm writing a code for a voting machine that will allow user to read in custom XML ballots and then vote on them, however in the current build I have in QtCreator, I don't see an easy way to edit buttons in my GUI directly. In the code snippet below, I assign an element to pull out the names and type of ballot being read in, but I need to append a label on the GUI as well as change buttons to the names of candidates read in. Any ideas on how to do this?
while(!n.isNull()){
QDomNode x = n.firstChildElement();
QDomElement e = n.toElement();
QMessageBox::information(0,
tr( "Loading Element" ),
tr( "Our element is %1" ).arg(e.tagName()) );
QDomElement p = x.firstChildElement();//p finds Races
QMessageBox::information(0,tr("Foo"),tr("p = %1").arg(p.text()));//finds Race and Ballot types
n = n.nextSibling();
}
}
All the widgets you created using the Designer UI are available from your code. How to access them depends on how you linked your UI with the rest of your classes (see http://doc.qt.io/archives/4.6/designer-using-a-ui-file.html) but if you used the multiple inheritance approach your widgets and layouts will be accessible directly from your class using the name under which they appear in Designer. Qt Creator's completion will even work with them.
Having that in mind you can easily use the usual methods to change a widget's name, add a label to a layout, etc.
If this is still unclear, please add the code you use to embed your GUI, as it is needed in order to give you a sensible code example.