I have placed two QGraphicsView's and one QLabel inside a horizontal layout (QHBoxLayout) with its layoutStretch set to 1, 1, 1. The problem is when I try to load images inside them, the images does not fill the widgets area. Here is the code:
QPixmap pix1("image1.jpg");
pix1 = pix1.scaled(ui->label1->size());
ui->label1->setPixmap(pix);
QPixmap pix2("image2.jpg");
pix2 = pix2.scaled(ui->graphicsView1->size());
ui->graphicsView1->scene()->addPixmap(pix2);
QPixmap pix3("image3.jpg");
pix3 = pix3.scaled(ui->graphicsView2->size());
ui->graphicsView2->scene()->addPixmap(pix3);
And here is the undesired output:
I have tried setting HorizontalPolicy and VerticalPolicy property of widget to Expanding and also Minimum, but none of them helped either.
Set size policy to QSizePolicy::Ignored and scale with Qt::KeepAspectRatioByExpanding:
ui->label1->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
pix1 = pix1.scaled(ui->label1->size(), Qt::KeepAspectRatioByExpanding);
ui->label1->setPixmap(pix);
You probably want to scale pixmaps in resizeEvent().
Related
I am trying to add a QLabel with an image to my GUI at runtime, but the scaling is ignored and the image expands to its full size (which is larger than the screen), ignoring the size constraints and not scaling the contents correctly.
The image should be fit into the bottom, left side of the window, as my GridLayout describes here:
headerPnl= new HeaderPnl();
buttonPnl = new ButttonPnl;
mainContentPnl = new QStackedWidget;
mainLayout = new QGridLayout;
mainLayout->setMargin(0);
mainLayout->setSpacing(0);
mainLayout->addWidget(headerPnl, 0, 0, 1, 7);
mainLayout->addWidget(mainContentPnl, 1, 0, 10, 6);
mainLayout->addWidget(buttonPnl, 1, 6, 10, 1);
mainLayout->setRowStretch(0,1);
mainLayout->setRowStretch(1,2);
mainLayout->setRowStretch(2,2);
mainLayout->setRowStretch(3,2);
mainLayout->setRowStretch(4,2);
mainLayout->setRowStretch(5,2);
mainLayout->setRowStretch(6,2);
mainLayout->setColumnStretch(0,1);
mainLayout->setColumnStretch(1,1);
mainLayout->setColumnStretch(2,1);
mainLayout->setColumnStretch(3,1);
mainLayout->setColumnStretch(4,1);
mainLayout->setColumnStretch(5,1);
mainLayout->setColumnStretch(6,1);
this->setLayout(mainLayout);
The header goes across the top, the button panel goes along the right side, and the rest of the screen is changing depending on the workflow of the application (ie what buttons are pressed, etc).
When necessary, my GUI replaces the widgets and updates the GUI like this:
void MainWindow::setContentPane(QWidget *content){
mainLayout->replaceWidget(contentPnl, content);
contentPnl = content;
}
void MainWindow::setButtonPanel(QWidget *buttonPanel){
mainLayout->replaceWidget(buttonPnl, buttonPanel);
buttonPnl = buttonPanel;
}
void MainWindow::configureWelcome(){
QLabel *welcomeLbl = new QLabel;
welcomeLbl->setObjectName("welcomeLbl");
welcomeLbl->setPixmap(QPixmap(":/images/welcome.jpg"));
welcomeLbl->setScaledContents(true);
CustomWidget *welcomeWidget = new CustomWidget;
QHBoxLayout *welcomeLayout = new QHBoxLayout;
welcomeLayout->addWidget(welcomeLbl);
welcomeWidget->setLayout(welcomeLayout);
setContentPane(welcomeWidget);
CustomWidget *buttonPnl = createWelcomeButtonPanel();
setButtonPanel(buttonPnl);
}
How can I make this image fit inside the GridLayout properly? It seems like when adding widgets to a layout that has already been set, the GUI doesn't know how to handle the size constraints from the GridLayout. Replacing the buttons works fine, but adding an image does not.
Side question: I have been trying to stay away from a QStackedWidget, as this application is designed for a lower power system, and it doesn't make sense to me to create all the possible screens and add them all to a QStackedWidget when the application starts. Instead I would rather use the resources when necessary, and only create all the GUI elements when I need to (ie, when the right buttons are clicked). Does that make sense?
Did you had a QSizePolicy to the widget containing the QGridLayout? I suggest an horizontal and vertical QSizePolicy::Fixed.
In your first code segment add :
this->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
1) How can I wrap text in a QGraphicsTextItem to fit a fixed rectangle, with width and height ?
Right now I am experimenting with creating a text, getting its bounding rectangle, and resizing it to fit the box - but I can't get wrapping.
class TTT: public QGraphicsTextItem {
TTT() {
{
setPlainText("abcd");
qreal x = m_itemSize.width()/boundingRect().width();
qreal y = m_itemSize.height()/boundingRect().height();
scale(x, y);
}
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
// experiment with clip regions
// text gets covered by hole in clip
QRegion r0(boundingRect().toRect());
QRegion r1(QRect(5, 5, 10, 10), QRegion::Ellipse);
QRegion r2 = r0.subtracted(r1);
painter->setClipRegion(r2);
painter->setBrush(Qt::yellow);
painter->drawRect(boundingRect());
QGraphicsTextItem::paint(painter, option, widget);
}
}
What makes wrapping happen, how can I trigger it ?
Right now, as I keep typing, the box is automatically expanding.
2) Is it possible to wrap the text in a QGraphicsItem / QGraphicTextItem subclass in a shape that is not a rectangle ?
(Something like in the image above)
I tried to use clipRegion, see code above, but I guess it is not the right way to go, clipping cuts the text but did not wrap.
Maybe it would... If I could figure out how to wrap text in the first place ?
Qt 4.8
You did not specify Qt version but try:
void QGraphicsTextItem::setTextWidth(qreal width)
Sets the preferred width for the item's text. If the actual text is wider than >the specified width then it will be broken into multiple lines.
If width is set to -1 then the text will not be broken into multiple lines >unless it is enforced through an explicit line break or a new paragraph.
The default value is -1.
In answer to 1) I'd opt not to use the QGraphicsTextItem, but draw the text directly in your QGraphicsItem's paint function using the drawText overloaded function, which takes a QTextOption parameter.
Using this, you can set the WrapMode, for example, with a call to
QTextOption::setWrapMode(QTextOption:: WordWrap)
As for 2) with a non-rectangular shape, I don't think Qt will do this for you.
Doing it yourself you can use QFontMetrics, to work out just how much text would fit in each line, depending upon where it lies within its bounding item.
Alternatively, you could adapt the concept of a text-to-path method.
I have a panel.ui file done using QTDesigner. It's a QFrame class, rectangular shape with few labels on it. And I have a QListWidget class where I insert 3 instances of the panel.ui.
I create a QListWidgetItem and then use List->SetItemWidget(..) to populate my list.
The Result is a list filled with three panels. I was also able to move the panels inside the list using dragDropMode internalMove.
I also tested the ability to shift the panels a bit to the right when I click on them and that worked:
in procedure List::mousePressEvent(QMouseEvent *event)
Panel *child = static_cast<Panel*>(childAt(event->pos()))
...
int y= child->pos().y();
int x = child->pos().x();
child->move (x +10, y); `
Problem: When I run the app and display the list, I want all the panels to be displayed with that 10 offset to the right. So in the List constructor and inside the loop after this->setItemWidget(myPanelItem, myPanel); I try using myPanel->move() like above but it doesn't seem to work.
I run the app, the panels are displayed without my offset ( not sure why?) but when I click on one, it shifts.
move() won't work reliably since the widgets are in a layout. (Well, not a layout as in a QLayout, but the effect is comparable: When any metric in your application changes, e.g. you resize or scroll the list, the widgets are repositioned by the list widget.)
What you can do is wrap your actual widget in a container widget with a layout margin:
QWidget* wrapIntoContainerForOffset(QWidget* widget, int offset /*in pixels*/) {
QWidget* container = new QWidget;
QHBoxLayout* layout = new QLayout(container);
layout->setContentsMargins(/*left=*/ offset, /*others=*/ 0, 0, 0);
layout->addWidget(widget);
return container;
}
Then you add these containers to the listwidget instead.
Have You tried StyleSheets. The QListWidget supports Box model( http://doc.qt.digia.com/qt/stylesheet-customizing.html#box-model ). So You may want to try playing around with margins in the stylesheets.
Style sheet reference: http://doc.qt.digia.com/qt/stylesheet-reference.html
IplImage *img_lb = cvCloneImage(img_orig);
QImage qt_img = IplImage2QImage(img_lb);
QLabel label_3;
// display on label
ui->label_3->setPixmap(QPixmap::fromImage(qt_img));
// resize the label to fit the image
ui->label_3->resize(ui->label_3->pixmap()->size());
// ui->label_3->show();
`hi i use Qt creator i would like to play video in the size of declared size and not his size ,someone can help?this is my code
If you want your Image scaled to you Label size, Use
ui->label_3->setPixmap(QPixmap::fromImage(qt_img).scaled(ui->label_3->size(), Qt::IgnoreAspectRatio));
This would make your pixmap perfectly fit to the Label while ignoring the aspect ratio. For more look here.
I have a QLabel and a QLineEdit inside a QWidget. When I have the widget inside a QScrollArea, the line edit does not expand to occupy the excess width of the window. When the widget is not inside the scroll area, it does expand.
I've tried setting the size policy of the line edit and the widget, to expand horizontally, but it doesn't occupy the excess space. I suspect the sizeHint() of the widget is compacted when inside a scroll area. Any ideas how to make this work?
class MainWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self, None)
self.setWindowTitle('Test Window')
self.resize(500, 250)
scrollArea = QtGui.QScrollArea()
scrollWidget = QtGui.QWidget()
scrollWidget.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Maximum)
layout = QtGui.QGridLayout(scrollWidget)
label = QtGui.QLabel("Name:")
layout.addWidget(label, 0, 0)
lineEdit = QtGui.QLineEdit("Value")
lineEdit.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Maximum)
layout.addWidget(lineEdit, 0, 1)
scrollWidget.setLayout(layout)
scrollArea.setWidget(scrollWidget)
self.setCentralWidget(scrollArea)
I believe I have solved your problem.
Make the following addition to your code and it should behave correctly:
...
scrollArea.setWidget(scrollWidget)
scrollArea.setWidgetResizable(True) #add this
self.setCentralWidget(scrollArea)
...
From the docs,
widgetResizable : bool
This property holds whether the scroll area should resize the view widget.
If this property is set to true, the scroll area will automatically resize the widget in order to avoid scroll bars where they can be avoided, or to take advantage of extra space.