Just a quick question.
I'm building my app interface at the moment with Qt.
I set a background image for the mainpage and I use stackedWIdgets to slide from one window to another.
setStyleSheet("background-image: url(:/spherebackground.png);"
"background-repeat: no-repeat;"
"background-position: center center");
When the application starts, a page appears which is made of 3 layouts:
1) One that contains a topToolbar Widget with QPushButtons, and a label displaying the PageTitle
2) in the middle, a mainPageLayout that contains the SlidingStackedWidgets
3) the BottomToolBar
The mainFrameWidget contains a mainFrameLayout:
mainPageWidget=new QWidget();
mainPageLayout=new QVBoxLayout();
//I add the buttons and others
mainPageLayout->addWidget(addEntryButton);
mainPageLayout->addWidget(vocaButton);
mainPageLayout->addWidget(exprButton);
mainPageLayout->addWidget(rulesButton);
mainPageLayout->addWidget(learnButton);
mainPageWidget->setLayout(mainPageLayout);
Then, I have the other pages created with the designer
And then a function that add the pages to the slidingStacked
void MainWindow::createSlidingStackedWidget() {
//the slidingStacked is the Widget that contains the subslidingWidgets
slidingStacked= new SlidingStackedWidget(this);
slidingStacked->addWidget(mainPageWidget);
quickAddView = new QuickAddController(); //which is a UI widget
slidingStacked->addWidget(quickAddView);
}
And then, when a button in the mainLayout is pressed, it triggers a function like this
void MainWindow::slideInAdd(){
topToolBar->clear();
slidingStacked->setVerticalMode(true);
slidingStacked->slideInIdx(1);
setupTopToolBar("Terminer","Ajout Entrée","Modifier");
bottomToolBar->hide();
QObject::connect(goBackButton,SIGNAL(clicked()),this,SLOT(backFromAdd()));
}
The thing is that I'm trying to port an application I created for the IPhone and I want it to have the same "Look and Feel" but when I slide from one page to another...
1) the animation flickers
2) I would like the sliding widgets to be transparent except for the controls (QPushButtons...)
but they have the same sphere background as the one I set up at the beginning of the code
3) My labels and controls also have the same background image when I would like them to be standard
(eg : a label should have a white background)
I can't figure out why...
Hope this will give you a better idea of what's going on...
So far as 2) and 3) go, that is because widgets inherit their parent's palette by default. To fix this, you can explicitly style them, or assign their palette to be the default application palette after they are created. I don't know how to handle the first problem.
Related
I started Qt Designer to create a window for the Maya tool.
I'm making the same GUI as Snap of Blender. How do I make the display change like this?
What is it called in Qt to show a different one for each button?
Two options I can think of
1. Use a StackedWidget (left)
A StackedWidget is a container that contains multiple widgets, but shows only one at a time. You can set which one is visible with .setCurrentIndex(int index) and .setCurrentWidget(QWidget*).
This is basically what you want to do, except by default it is going stay as tall as the tallest widget, even with a spacer (as visible on the screenshot).
This can be forced manually, or you can even create your own widget to do that (https://www.qtcentre.org/threads/28514-How-can-i-achieve-an-auto-resizing-QStackedWidget), but it defeats a bit its ease of use.
2. Widgets, hide/show, spacer (right)
The second option, really basic, is to create different Widgets that will act as containers, and that you will toggle (.show()/.hide) whenever a button is pressed. This can even be done from the Designer of QtCreator if you are looking for the easiest way to achieve it.
Make your buttons checkable, and exclusive (as you probably did)
Connect to the clicked(bool checked) or toggled(bool checked) signal
Call show/hide on the container widgets to show only one. Et voila!
MyWidget:MyWidget(...)
{
connect(ui->vertexButton, &QPushButton::clicked, this, &MyWidget::onButtonClicked);
}
void MyWidget::onButtonClicked(bool checked) {
button = sender();
if (button == ui->vertexButton) {
ui->vertexContent->show();
ui->edgeContent->hide();
} else if ...
}
Disclaimer: I haven't tried to compile the code above
So, I've been programming an analog clock in JavaFX and have gotten the base functionality down. Now, I'm trying to add a drop-down menu when I click a custom button (triangle made with a Polygon). So far it all works fine, except the fact that the background of my StackPane is white when I try to add a ContextMenu either before or after clicking the button. So far Transparency has been fine up until now. Here's some pictures of the issue.
This is what it should look like (you can see my wallpaper because of the transparent window, as it should be.)
enter image description here
After I press the button for the drop down menu, the background changes.
enter image description here
JavaFX controls are styled by CSS. The first time you create a control, the default user agent stylesheet (modena.css) is loaded and the styles defined in it are applied to the scene graph. Other JavaFX node classes, such as shapes, image views, and layout panes, do not enforce CSS loading (this is to enhance performance for graphically-intensive applications that do not need CSS).
So it sounds as though the context menu is the first control you create: when you create and display it, it will apply the default CSS to the scene. The default background color for the root pane is a non-transparent color, so while your Scene and Stage may be transparent, once the CSS is applied the scene's content is not.
The fix is to specify transparency for the root pane:
root.setStyle("-fx-background-color: transparent;");
or the equivalent in an external stylesheet.
To answer my own question in case anyone else wants to know, it seems that when the ContextMenu is added to the scene, the Stage's initStyle(StageStyle.TRANSPARENT) gets overridden and shows the Parent's colors. Since I didn't initialize any CSS styles for the root, it just showed white. The fix would be to:
//the Parent layout Pane
parent.setStyle("-fx-background-color: rgba(0, 0, 0, 0.0)");
Currently I have a set of buttons in a QVBoxLayout which is inside a QHBoxLayout.
Is there a way to move these according to where my mouse is?
My current code is like this:
self.button1 = QPushButton()
self.button1.setText("button A")
self.button2 = QPushButton()
self.button2.setText("button B")
vbox = QVBoxLayout(self.canvas)
vbox.addStretch(1)
vbox.addWidget(self.button1)
vbox.addWidget(self.button2)
hbox = QHBoxLayout(self.window)
hbox.addStretch(1)
hbox.addLayout(vbox)"
The prototype for moving some button widget would be:
vbox.removeWidget(self.button) // that only needs the reference to your button item
vbox.insertWidget(newPos, self.button) // mind the difference in target position when you remove one item
That does not cover event processing. With two buttons you can either do that twice for each or maybe altogether, mind the target positions.
Or you can move an entire layout within another layout for the group of buttons in a very similar fashion. That'd be moving layout item. As long as you don't imply those buttons cannot be moved separately the example is for individual buttons. Oh, there is some Qt C++ discussion about that.
I am a newbie to Qt and facing issue in my application. So here is what I am trying to do.
I have a class with QWidget as parent. This class has a grid layout on it. I set this widget as a central widget to main window. (this thing worked fine though this widget is not centered on Main Window.)
Now I wanted to rotate this widget in 90 degrees so that it can bee shown on device in landscape mode. So I created a graphics view and added this widget to it. (created a scene added widget to that and assigned scene to view.) then this graphics view was rotated and made central widget. this worked amazingly and it was very well centered, looked good on device as well.
But in final integration we want to have all QWidgets so Graphics View is not an option. To tackle this I created a Qwidget member inside my class. applied the layout to it. added this widget to graphicsView and my class was made parent to it.
This also works but has the similar issue I faced in first step, it sits in the top left corner of MainWindow and does not adjust to center. To make things even worse, when deployed on device it was not applied to entire screen. Widget was sitting in some part of top left area and had scroll bars to it! I even tried the set Window State to maximized but had no effect on it.
Here is what I tried
The widget is created inside my class and been added to Graphics View. this view has my class as parent and it will be rotated by using rotate api.
m_gridContainer = new QWidget();
m_gridContainer->setAutoFillBackground(true);
m_gridContainer->setPalette(blackPalette);
m_gridContainer->setLayout(m_grid);
m_gridContainer->setMinimumSize(480,265);
m_scene = new QGraphicsScene(0, 0, 480, 265);
m_window = new QGraphicsView(m_scene,this);
m_scene->setBackgroundBrush(brush);
m_window->setAlignment(Qt::AlignCenter);
m_scene->addWidget(m_gridContainer,Qt::Widget);
To use it from main Window
m_window = new CMyWidget(label, m_txtBox->text());
m_window->getRotatedWidget(90);
setCentralWidget(m_window);
I tried whatever I can but this widget is not being shown full screen (in just a small area) and still have scroll bars to it. I have no idea what exactly is happening there.
m_gridContainer being a graphics item part of a graphics scene, it doesn't receive the resize events of you main window.
You have to handle the resizeEvent() on your CMyWidget and adjust the size of your m_gridContainer accordingly, e.g.
void CMyWidget::resizeEvent ( QResizeEvent * event )
{
m_gridContainer->resize(event->size());
}
BTW, if you are handling the rotation for use on a mobile device, it is managed by Qt itself (by simply resizing your main window). You don't have to do it in your code (you'll actually end up with a widget looking like it has been rotated twice).
I'm trying to create a custom tab navigator that has to look like this http://www.freeimagehosting.net/uploads/b470d024c4.jpg.
Also, when there's a rollover, the borders of the arrow have to be in blue (like the label in the current tab).
For that purpose, I've created a custom component: a hbox containing a label and a canvas with 3 images inside (for the arrow tip that has to change depending on the currentState).
Then, I thought of overlapping the components in order to get the blue highlight color (ex: arrow button 3 is over arrow button 4. The image of the arrow tip in button 3 will be transparent outside the arrow, so that we can see the black color of the following button).
I'm now trying to position the components inside the canvas ... but I cannot.
After the creationComplete event, I assign the label text and I was calculating the coordonates of the component but it doesn't take into account the label width... -_-'
Any ideas?
Thanks. Regards,
BS_C3
Read up on the Flex Component LifeCycle. You should be positioning and sizing your child components in the updateDisplayList() method; not in a creationComplete handler.
You should assign the label text in either commitProperties or createChildren depending upon when you know what it is.
If you want to share some code, we may be able to hone in on the exact problem. If you run code like this:
myLabel.text = 'Blahblahblahblah';
trace(myLabel.width);
I would expect that the width has not changed to reflect the new text because the myLabel has not gone through it's own component lifecycle steps yet.