All Qt Charts seem to have a margin and rounded corners.
How to remove both?
I want the white area to fill the entire dialog. I cannot find any informations in the Qt documentations. I found a screenshot of one Example that does not have this spacing. But I cannot find the code that disables it.
My initialization code looks like this:
QPieSeries *series = new QPieSeries();
series->append("Jane", 1);
series->append("Joe", 2);
series->append("Andy", 3);
series->append("Barbara", 4);
series->append("Axel", 5);
QChart *chart = new QChart();
chart->addSeries(series);
QChartView *chartView = new QChartView(chart);
chartView->setBackgroundBrush(Qt::red);
chartView->setRenderHint(QPainter::Antialiasing);
QMainWindow window;
window.setCentralWidget(chartView);
window.resize(400, 300);
window.show();
Devopia answerd the question in the comments!
In my example above I needed the following 2 lines of code to remove the red part completely:
chart->layout()->setContentsMargins(0, 0, 0, 0);
chart->setBackgroundRoundness(0);
At Qt 5.11 this does not work because the layout() method const (inherited from QGraphicsWidget):
QGraphicsLayout *QGraphicsWidget::layout() const
Furthermore it is not possible to take a copy of this because QGraphicsLayout is a base class.
For me this works:
chart->setMargins(QMargins(0,0,0,0));
Related
I'm trying to create a panel of buttons that will have 4 buttons, a space, and another button, all of equal space, like this:
I have tried to use Spacers, but it seems like those require a specific height and weight, and I would like this layout to be dynamic enough to appear correctly on any resolution, so a fixed size Spacer would not work.
I have tried to following code, but this just squishes the first 4 buttons to the top and the last one to the bottom, and doesn't space them out evenly.
QVBoxLayout *layout = new QVBoxLayout;
layout->setMargin(15);
layout->setSpacing(15);
layout->addWidget(button1, 1);
layout->addWidget(button2, 1);
layout->addWidget(button3, 1);
layout->addWidget(button4, 1);
layout->addWidget(button5, 2, Qt::AlignBottom);
layout->addStretch();
buttonPnl->setLayout(layout);
I also tried using a QGridLayout and specifying the height of each row, but this looks the same as the previous example.
QGridLayout *gridLayout = new QGridLayout;
gridLayout->setMargin(15);
gridLayout->setSpacing(15);
gridLayout->addWidget(button1, 0, 0);
gridLayout->addWidget(button2, 1, 0);
gridLayout->addWidget(button3, 2, 0);
gridLayout->addWidget(button4, 3, 0);
gridLayout->addWidget(button5, 5, 0);
gridLayout->setRowStretch(0, 1);
gridLayout->setRowStretch(1, 1);
gridLayout->setRowStretch(2, 1);
gridLayout->setRowStretch(3, 1);
gridLayout->setRowStretch(4, 1);
gridLayout->setRowStretch(5, 1);
How can I create a dynamic layout that will display my buttons correctly at any reasonable resolution?
It's a little bit ``hacky-slash'' but... the easiest way to get the desired behaviour is probably to define a spacer class that inherits from QPushButton but has an empty paintEvent definition...
class spacer: public QPushButton {
using super = QPushButton;
public:
using super::super;
protected:
virtual void paintEvent (QPaintEvent *event) override
{
}
};
Then just make sure you instantiate it with a text string that's in keeping with the other buttons so that it has a suitable return value from sizeHint(). So (based on your own example)...
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(button1);
layout->addWidget(button2);
layout->addWidget(button3);
layout->addWidget(button4);
/*
* Add a spacer using the text from button4 as a reference.
*/
layout->addWidget(new spacer(button4->text()));
layout->addWidget(button5);
layout->addStretch();
buttonPnl->setLayout(layout);
This gives me something like...
I have to write a simple video player that can display some subtitles,link or a picture(like on YouTube) in a certain time. I have no idea of how do display anything using QVideoWidget. I couldn't find any useful class to do it. Could you please give me some advices?
I did It your way but after i load any video QLabel disappears...
player->setVideoOutput(vw);
playlistView->setMaximumWidth(200);
playlistView->setMinimumWidth(300);
window = new QWidget;
Playerlayout = new QGridLayout;
subtitleWidget = new QLabel;
subtitleWidget->setMaximumWidth(1000);
subtitleWidget->setMaximumHeight(100);
subtitleWidget->setStyleSheet("QLabel {background-color : red; color
blue;}");
subtitleWidget->setAlignment(Qt::AlignCenter | Qt::AlignBottom);
subtitleWidget->setWordWrap(true);
subtitleWidget->setText("example subtitle");
Playerlayout->addWidget(vw,0,0);
Playerlayout->addWidget(subtitleWidget,0,0);
Playerlayout->addWidget(playlistView,0,1,1,2);
If QVideoWidget doesn't provide what you require directly then you could always set up an overlay.
The basic layout item hierarchy would be something like...
QWidget
layout
QVideoWidget
subtitle_widget
In this case the layout could be either a QStackedLayout using stacking mode QStackedLayout::StackAll or a QGridLayout with both the QVideoWidget and the subtitle_widget occupying the same cells but with the correct z-order.
Going with the QGridLayout...
auto *w = new QWidget;
auto *l = new QGridLayout(w);
auto *video_widget = new QVideoWidget;
auto *subtitle_widget = new QLabel;
/*
* Subtitles will be shown at the bottom of the 'screen'
* and centred horizontally.
*/
subtitle_widget->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
subtitle_widget->setWordWrap(true);
/*
* Place both the video and subtitle widgets in cell (0, 0).
*/
l->addWidget(video_widget, 0, 0);
l->addWidget(subtitle_widget, 0, 0);
Subtitles etc. can now be displayed simply by invoking subtitle_widget->setText(...) at the appropriate time.
The same method can easily be extended to overlaying other types of information.
In Qt Designer , you can drag a "Line" widget , which will create a line in your layout.
But I checked the document and headers , I didn't find the "Line" header / widget , what was it ?
In Qt 5.7 the code generated by Qt Designer for a Horizontal Line (which can be checked in the menu using "Form/View Code...") is:
QFrame *line;
line = new QFrame(Form);
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
This will create the lines you see in Qt Designer.
The current answers do not seem to give working solutions, here is a comparison of all answers (this solution is the first line):
Full code:
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QWidget widget;
auto layout = new QVBoxLayout;
widget.setLayout(layout);
widget.resize(200, 200);
auto lineA = new QFrame;
lineA->setFrameShape(QFrame::HLine);
lineA->setFrameShadow(QFrame::Sunken);
layout->addWidget(lineA);
QWidget *lineB = new QWidget;
lineB->setFixedHeight(2);
lineB->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
lineB->setStyleSheet(QString("background-color: #c0c0c0;"));
layout->addWidget(lineB);
auto lineC = new QFrame;
lineC->setFixedHeight(3);
lineC->setFrameShadow(QFrame::Sunken);
lineC->setLineWidth(1);
layout->addWidget(lineC);
QFrame* lineD = new QFrame;
lineD->setFrameShape(QFrame::HLine);
layout->addWidget(lineD);
widget.show();
return app.exec();
}
I guess you mean a horizontal / vertical line widget: it's just a simple QWidget with a gray background color and the horizontal is a fix height (1-3 pixel) and expanding width widget, the vertical is a fix width expanding height widget.
Horizontal example code:
QWidget *horizontalLineWidget = new QWidget;
horizontalLineWidget->setFixedHeight(2);
horizontalLineWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
horizontalLineWidget->setStyleSheet(QString("background-color: #c0c0c0;"));
Check out QFrame::setFrameShape(). To get a line, use either QFrame::HLine or QFrame::VLine as the function's argument.
// Create a horizontal line by creating a frame and setting its shape to QFrame::HLine:
QFrame* hFrame = new QFrame;
hFrame->setFrameShape(QFrame::HLine);
// Create a vertical line by creating a frame and setting its shape to QFrame::VLine:
QFrame* vFrame = new QFrame;
vFrame->setFrameShape(QFrame::VLine);
It is a QFrame with height 3, sunken shadow and line width equal to 1.
You can see it if examine header generated by uic tool.
I want to show difference between a trimed clip and non trimed clip in my video editor application, i.e. I want to add a small film image on my thumbnail for a trimed clip. How can I do this?
It would be just to show the difference between an image and a video in our gallery application.
How to add an image on the top of another one in Qt?
Open the QPainter on the bottom image and draw the top image using its drawPixmap()/drawImage() methods.
QPixmap base, overlay; // come from your code
{
QPainter painter(base);
painter.drawPixmap(100, 100, overlay);
}
If your overlay contains an alpha channel (e.g. fancy PNG icon) and your base image does not, you should create a new QPixmap with an alpha channel and draw both images into it:
QPixmap base, overlay; // come from your code
QPixmap result(base.width(), base.height());
result.fill(Qt::transparent); // force alpha channel
{
QPainter painter(&result);
painter.drawPixmap(0, 0, base);
painter.drawPixmap(100, 100, overlay);
}
QPixmaps and QImages can be used interchangeably, although not all combinations give good performance).
If it's just about showing an image above another, then you could also go with this answer.
QGridLayout *layout = new QGridLayout(widget);
Pixmap base, overlay;
QLabel *background = new Label();
background->setPixmap(&base);
QLabel *lOverlay = new QLabel();
lOverlay->setPixmap(&overlay);
//label gets positioned above textBrowser and is an overlay
layout->addWidget(background, 0, 0, Qt::AlignLeft | Qt::AlignTop);
layout->addWidget(lOverlay, 0, 0, Qt::AlignRight | Qt::AlignBottom);
Of course then the QPixbuf of the background doesn't contain the QPixbuf of the overlay-image, but it only appears to do.
I'm trying to build programmaticaly (with Qt 4.6) a window containing a series of QPushButton's, all packed together. It should look like so (which I call a toolbox):
toolbox image http://img99.imageshack.us/img99/9853/examplezk.png
So, I created a Toolbox class, deriving from QWidget, that has the following constructor:
Toolbox::Toolbox (void)
: QWidget (0, Qt::Tool)
{
setWindowTitle (tr ("Toolbox"));
QGridLayout *group = new QGridLayout (this);
group->setSpacing (0);
group->setContentsMargins (0, 0, 0, 0);
group->setSizeConstraint (QLayout::SetFixedSize);
setLayout (group);
unsigned k = 0;
QPushButton *buttons = new QPushButton[6];
for (unsigned i = 0; i < 3; i++)
for (unsigned j = 0; j < 2; j++)
{
buttons[k].setIcon (QIcon ("test.png"));
buttons[k].setIconSize (QSize (32, 32));
buttons[k].setContentsMargins (0, 0, 0, 0);
buttons[k].setCheckable (true);
buttons[k].setAutoExclusive (true);
group->addWidget (&buttons[k], i, j);
k++;
}
buttons[1].setChecked (true);
Somehow, it does not work and my buttons don't end up packed together:
result http://img9.imageshack.us/img9/774/resultr.png
I can't manage to remove this vertical spacing (and the margins surrounding the entire array). Any help is welcome.
Apparently, this is considered a normal thing: see the corresponding bug report, which was closed. The workaround reported there doesn't seem to work for me.
Since you've set the size constraint on the layout to QLayout::SetFixedSize, Qt will use the size hint of the widget as its fixed size. You might have to override QWidget::sizeHint() in the Toolbox class to make the widget exactly as large as it needs to be to fit all the buttons (in the case of your six buttons, the width would be 64 and the height would be 96).
If you are using the the plastique style which is now standard in Qt4.6 the borders of QPushButtons are drawn inside the widget. Try using one of the other styles. e.g.:
#include <QGtkStyle>
QApplication a(argc, argv, true);
a.setStyle("gtk");
A style can also be set on an individual widget using the QWidget::setStyle() function.