Why can't I add my widget to the layout? It is like the example for adding Widgets...
My aim is to draw into a small QWidget, whichs purpose is only to hold that painted element.
void Note::paintEvent(QPaintEvent *event)
{
paintExample = new(QWidget);
paintExample->setGeometry(500,500,500,500);
paintExample->setStyleSheet("background:yellow");
QImage *arrowImg = new QImage(100,100,QImage::Format_RGB32);
QHBoxLayout *lay = new QHBoxLayout;
lay->addWidget(arrowImg); //Error: no matching function for call to 'QHBoxLayout::addWidget(QImage*&)'
paintExample->setLayout(lay);
QPainter painter(arrowImg); //Must paint on QImage/QPixmap/QPicture, QWidget not possible?
if (painter.isActive()){
painter.begin(arrowImg);
painter.setPen(Qt::black);
QRect rect = QRect(50,25,60,40);
painter.drawRect(rect);
painter.end();
}
paintExample->show();
}
In the class header in private area:
QWidget * paintExample;
Read the documentation carefully:
QHBoxLayout, and any other layout, could only hold items inheriting from QLayoutItem, which are QLayout itself, QSpacerItem and QWidgetItem. Create QWidget and paint on that.
QPainter constructor accepts descendants from QPaintDevice and QWidget is among those, so it's totally possible.
Now, to other issues:
You create parentless objects in paintEvent() without deleting them. Not only this method could be called quite frequently, this approach to painting is not good at all. As I understand Note is a QWidget already, so you're free to paint on it right away, with QPainter painter(this);.
Operations with layout are most definitely not meant to be done in paintEvent() either, as well as showing/hiding widgets. Do this somewhere else, e.g. in your window/dialog constructor.
Why can't I add my widget to the layout?
Because QImage is not a QWidget. That's why. You should probably wrap the image in a QLabel:
QLabel arrowLabel;
arrowLabel.setPixmap(QPixmap::fromImage(*arrowImg));
and pass that to the layout:
lay->addWidget(arrowLabel);
Related
I've made a QT Designer Form called DropDownMenu. Essentially it is just a QWidget with a QVBoxLayout inside of it.
DropDownMenu has a function that pragmatically adds buttons to it.
QPushButton* DropDownMenu::AddButton(
const QString& text)
{
QPushButton* new_button = new QPushButton(text, this);
m_ui->LayoutManager->addWidget(new_button);
return new_button;
}
I then add a QWidget to my MainWindow inside of QT Designer & promote this widget to DropDownMenu. Then I add buttons to this new QWidget using the AddButton function.
The end result looks like this...
I want to make it so the containers scale according to how many buttons or widgets are placed inside of the layout, but they seem to just get squeezed together so that they fit the parents default size.
How can I make it so the parent scales to the size of all it's children?
In a custom QWidget (say MyWidget) I include a layout to manage children widgets:
MyWidget window;
QPushButton button;
QVBoxLayout layout(window);
layout.addWidget(button);
window.show();
I would like the layout to be in a specific position and size, by default, QWidget set it to the whole geometry.
How can I set the geometry the layout will consider for managing his space?
As an indirect question:
Which function the layout use to set children geometries?
QPushButton *button = new QPushButton;
verticalLayout->addSpacing(300);
verticalLayout->addWidget(button);
button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
button->setMinimumSize(500, 200);
button->setMaximumSize(500, 200);
If you need both vertical and horizontal spacing - use QGridLayout.
The QLayout use as margins the summary of both:
The parent widget contents margins.
The layout contents margins.
The solution is to set the contents margins to the required value in the custom widget constructor. And when creating the layout, to set his contents margins to 0.
this->setContentsMargins(left, top, right, bottom);
// ...
layout->setContentsMargins(0,0,0,0);
The Layout setGeometry is called by QWidget resize event, and set children widgets size according with it. As all functions are not virtual, it is not possible (or at least difficult) to modify in this behavior.
i'm stuck with a simple Function of Qt that does not work for me.i made a class that inherits
from QMainWindow and another class that inherits from QWidget.then i made from the second a member object(a pointer to) inside the first and assigned it as its centralWidget during the construction of my window.
when it comes to adjust my centraWidget inside the window with the function QWidget::setGeomerty() it simply don't work.here's my code:
void MainWindow::show()
{
//some code that centers my window on the screen
int margin=this->width()/7;
centralWidget()->setGeometry(margin,centralWidget()->geometry().top(),this->width()-margin,centralWidget()->geometry().bottom());
QMainWindow::show();
}
i know it might be stupid but i just can't figure it out.help me.
QMainWindow has its own layout in which the center area is occupied by the central widget. So it won't be pretty straightforward to break that layout and modify the central widget size / position arbitrarily.
What I recommend is to use a placeholder central widget and add your widget as a child.
I'm pretty sure you can achieve what you want by setting a proper Qt built in layout to the "placeholder" central widget and then adding your widget to the layout.
layouts was necessary to manage what i want; i think it's not possible to hand directly over the central widget and try to move/resize it;but by adding a layout and a child widget, we can dispose of them.here is my code:
mainwindow.cpp
// i focused on my window constructor
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
m_MainView(new MainView(this)),
m_WindowLayout(new MainWindLayout(NULL))//my custom layout witch just inherits from QGridLayout
{
//.............
setCentralWidget(m_MainView);
m_WindowLayout=new MainWindLayout(m_MainView);//my layout set into my central Widget"m_MainView".
QWidget *temp(dynamic_cast<QWidget *>(m_MainView->centralView()));//centralView() returns a child QWidget of my central Widget
QMargins margins(this->width()/5,0,this->width()/5,0);//setting up layout margins :left,top,right,bottom;exactly what i need
m_WindowLayout->setContentsMargins( margins);
m_WindowLayout->addWidget(temp,0,0,-1,-1);//adding my child widget to the layout filling all cells of the gridlayout.
}
thanks everybody
I have a QMainWindow whose central widget has been set to a QGraphicsView viewing a black scene (for test purposes). Note that in the code below, I use my class derived from QGraphicsView, called CQtGlView, which reimplements only the resizeEvent function.
Regardless of whether I add the view directly,
CQtMainWindow::CQtMainWindow() {
m_glView = new CQtGlView();
setCentralWidget(m_glView);
}
or stick it in a layout with margins of 0 in a dummy widget,
CQtMainWindow::CQtMainWindow() {
m_glView = new CQtGlView();
QWidget* dummy = new QWidget();
QHBoxLayout* l = new QHBoxLayout();
l->setContentsMargins(0,0,0,0);
l->addWidget(m_glView);
dummy->setLayout(l);
setCentralWidget(dummy);
}
I get an unwanted grey border around the widget.
The screenshot below illustrates the problem, visible between my scene and the windows aero border.
This would not be a problem if my application did not allow switching to full screen. The border is very obvious once the rest of the screen is black.
It's possible this area represents the DockWidgetAreas around the outside of the central widget.
Is there anything I can do to solve this other than not use QMainWindow? (Undesirable due to my use of menuBar, tool bars, and statusBar.)
It turns out that QGraphicsView derives from QFrame, where I assumed it was only a QWidget.
The solution to this problem was to call setFrameStyle(QFrame::NoFrame); in the constructor of my QGraphicsView subclass. Or if it was not a subclass,
m_glView->setFrameStyle(QFrame::NoFrame);
Have you tried setFrameShape(QFrame::NoFrame) on the QGraphicsView?
I create a class which is a subclass of a QWidget used for painting a image, only for painting a image, named ImageWidget.
When I only create a ImageWidget and call ImageWidget.show(), everything is fine. Then I create another QWidget subclass like below. At present, only shows the combox and slider, the image does not show. Could someone help me about it?
MainWindow::MainWindow(QWidget *parent) :
QWidget(parent)
{
imgWidget=new ImageWidget(this);
fractalTypeLabel=new QLabel(tr("Type"));
typeCombo=new QComboBox();
typeCombo->addItem(tr("One"));
typeCombo->addItem(tr("Two"));
scalefactorLabel=new QLabel(tr("Scale Factor"));
scalefactorSlider=new QSlider(Qt::Horizontal);
scalefactorSlider->setTickInterval(1);
scalefactorSlider->setTickPosition(QSlider::TicksBelow);
QVBoxLayout *imageLayout=new QVBoxLayout();
imageLayout->addWidget(imgWidget);
QGridLayout *gridLayout=new QGridLayout;
gridLayout->addWidget(fractalTypeLabel,0,0);
gridLayout->addWidget(typeCombo,0,1);
gridLayout->addWidget(scalefactorLabel,1,0);
gridLayout->addWidget(scalefactorSlider,1,1);
QHBoxLayout *mainLayout=new QHBoxLayout;
mainLayout->addLayout(imageLayout);
mainLayout->addLayout(gridLayout);
this->setLayout(mainLayout);
}
Best Regards,
Most Likely you are not reporting a size for your widget from sizeHint, in your custom subclass implement virtual QSize sizeHint () const and return something. Your widget will probably show. In the absence of sizeHint the system thinks that your widget can be of size 0x0 and eliminates it from the layout. There are other ways around this by playing with the layout settings. It is slightly non-intuitive ... . You might want to implement some of the other size related functions in from QWidget