The followin code creates a QTableWidget with some content.
void MainWindow::on_pushButton_clicked()
{
m_tbl = new QTableWidget;
qDebug() << m_tbl->sizeHint(); // output "QSize(256, 192)"
qDebug() << m_tbl->sizePolicy();
/* above line outputs "QSizePolicy(horizontalPolicy = QSizePolicy::Policy(Expanding), verticalPolicy = QSizePolicy::Policy(Expanding))" */
m_tbl->setRowCount(4);
m_tbl->setColumnCount(2);
m_tbl->horizontalHeader()->setVisible(false);
m_tbl->verticalHeader()->setVisible(false);
m_tbl->setItem(0,0,new QTableWidgetItem(QString("0,0")));
m_tbl->setItem(0,1,new QTableWidgetItem(QString("0,1")));
m_tbl->setItem(1,0,new QTableWidgetItem(QString("1,0")));
m_tbl->setItem(1,1,new QTableWidgetItem(QString("1,1")));
m_tbl->setItem(2,0,new QTableWidgetItem(QString("2,0")));
m_tbl->setItem(2,1,new QTableWidgetItem(QString("2,1")));
m_tbl->setItem(3,0,new QTableWidgetItem(QString("3,0")));
m_tbl->setItem(3,1,new QTableWidgetItem(QString("3,1")));
m_tbl->adjustSize(); // not making any difference
m_tbl->show();
}
The problem is the window size is larger than the content - please see the image below. How could one let the window adjust its size according to its content in this case?
Thanks in advance.
Related
I need to be able to print from qt (the rendered contents of a QGraphicsScene, or a QImage), to scale, on normal printer, pdf, but also on custom printers, including roll fed.
It seems that anything that works for standard printers fails on custom printers, and the reverse.
I have made the printing work as expected on custom printers now (going back and forth between what works in the different printers).
I set the custom size required, and the preferred orientation, based on length/width ratio.
I open a print dialog (and even check the supply- the paper is set to desired size, and the orientation is set as expected)
print:
On custom printer, I get the correct size, and if the supply is smaller, the print clips as needed. margins are set correctly too.
On Pdf, I get a document of custom size as requested, printed correctly - but the orientation is not respected !!! (even though print dialog showed it correctly) - see image
On HP printer, I get a white page - nothing gets printed.
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QPrinter>
#include <QPrintDialog>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// some scene to print - show rectangle for easy measure
QGraphicsScene* s = new QGraphicsScene();
s->setSceneRect(-500, -500, 1500, 1500);
s->setBackgroundBrush(Qt::red);
QGraphicsView* view = new QGraphicsView();
view->setScene(s);
view->show();
qreal in = 72;
QRectF canvasRect(-0.1*in, -0.1*in, 6*in, 4*in);
qreal margins = 0.1*in;
QRectF actualCanvasRect = canvasRect.adjusted(margins,margins,-margins,-margins);
// this is to show actual scene
QGraphicsRectItem* contourItem = new QGraphicsRectItem(actualCanvasRect);
contourItem->setBrush(Qt::blue);
s->addItem(contourItem);
// an item partially on canvas (so I can check margins)
QGraphicsRectItem* item = new QGraphicsRectItem(-.5*in, -in, 2*in, 3*in);
item->setBrush(Qt::yellow);
s->addItem(item);
// actual printing:
// print the scene, to scale, using user margins, on given printer
QPrinter printer;
QPrinter::Orientation orient = (actualCanvasRect.width() >
actualCanvasRect.height() ?
QPrinter::Landscape : QPrinter::Portrait);
printer.setOrientation(orient);
printer.setPaperSize(canvasRect.size(), QPrinter::Point);
printer.setPageMargins(margins, margins, margins, margins, QPrinter::Point);
QPrintDialog printDialog(&printer);
if (printDialog.exec() != QDialog::Accepted)
{
qDebug("dialog canceled");
return 1;
}
QPainter painter;
if (! painter.begin(&printer))
{
qDebug("failed to open printer");
return 1;
}
// render the contents, clipped to printer page size, and scaled from point to device pixel
QRectF source = actualCanvasRect;
// convert target rect to DevicePixel and clip to page
QRectF page = printer.pageRect(QPrinter::DevicePixel);
qreal scale = printer.resolution()/in;
QRectF target = QRectF(page.topLeft(), source.size() * scale);
target &= page; // clip target rect to page
// clip source rect to page - without this, if printer paper is smaller I get unwanted scaling
source &= printer.pageRect(QPrinter::Point);
s->render(&painter, target, source);
painter.end();
return app.exec();
}
I don't understand why pdf creates a portrait page even though I clearly requested landscape (without changing the print dialog: see image). (the width and height are reversed, yet correct - Document Properties shows 4x6, and the page attempts to print correctly and to scale)
More important, I don't understand why a typical laser jet printer prints nothing - blank page - or sometimes for a simple canvas it scales to fit.
BUT if I change any properties in the print dialog from HP, anything irrelevant (like paper source, or paper type.... ), it prints correctly.
What am I doing wrong ?
(using Qt 4.7 and 5.5, must work on 4.7 - Windows, have yet to try Linux)
I want to draw some text in the end of menu bar like this
But when the child window is maximized in the MDI project it looks like this
I need to fix this output.
I want to check if the active child is maximized and if it is I want to get minimize/restore/close rectangle to get them total width.
How can I get active child window and how can I get it's rectangle of buttons?
// in yourMainWindow.cpp
...
auto child = mdiArea->addSubWindow(yourWidget);
connect(child, &QMdiSubWindow::windowStateChanged, this, &yourMainWindow::yourSlot);
...
void yourMainWindow::yourSlot(Qt::WindowStates oldState, Qt::WindowStates newState)
{
if (newState.testFlag(Qt::WindowMaximized)) {
auto child = qobject_cast<QMdiSubWindow *>(sender());
if (!child)
return;
QStyleOptionComplex opt;
opt.initFrom(child);
auto size = child->style()->sizeFromContents(QStyle::CT_MdiControls, &opt, QSize(100, 20));
qDebug() << size;
}
}
I constantly generate new HTML pages that I display in a QWebView. Now I have trouble to restore the current position of the vertical scrollbar after the setHtml() call, if the HTML contains images. The scrollbar always jumps back to the top.
The following code works as long as the HTML only contains text:
void MainWindow::htmlResultReady(const QString &html)
{
// remember scrollbar position
int scrollBarPos = ui->webView->page()->mainFrame()->scrollBarValue(Qt::Vertical);
ui->webView->setHtml(html);
// restore previous scrollbar position
ui->webView->page()->mainFrame()->setScrollBarValue(Qt::Vertical, scrollBarPos);
}
I also tried to use the signal QWebView::loadFinished() without success:
void MainWindow::setupHtmlPreview()
{
connect(ui->webView, SIGNAL(loadFinished(bool)),
this, SLOT(restoreScrollBarPosition()));
}
void MainWindow::htmlResultReady(const QString &html)
{
// remember scrollbar position
scrollBarPos = ui->webView->page()->mainFrame()->scrollBarValue(Qt::Vertical);
ui->webView->setHtml(html);
}
void MainWindow::restoreScrollBarPosition()
{
// restore previous scrollbar position
ui->webView->page()->mainFrame()->setScrollBarValue(Qt::Vertical, scrollBarPos);
}
Perhaps the size of the page changes. Call setScrollBarValue when contentsSizeChanged is emitted by the frame (typically webView->page()->mainFrame()).
I am trying to design a sudoku game with a grid layout full of qpushbuttons, At the momment of inserting a number in of the qpush button whihch is triggered when clicking on them I need to check if its a valid move depending on the other "cells". My problem is that i need the row and column of the qpushbutton that was clicked in qgridlayout but havent been able to find how to do it. Is there some way to obtain the coordinates of the qpushbutton clicked on the qgridlayout?
http://doc.qt.io/qt-4.8/layout.html#horizontal-vertical-grid-and-form-layouts
http://doc.qt.io/qt-4.8/qgridlayout.html#getItemPosition
http://doc.qt.io/qt-4.8/qlayout.html#indexOf
Your code should look something like:
int index = my_grid_layout->indexOf(clicked_widget);
if(index != -1)
{
int row, col, col_span, row_span;
my_grid_layout->getItemPosition(index, &row, &col, &col_span, &row_span);
qDebug() << "Clicked Item is at:" << row << col
<< "spanning" << row_span << col_span;
}
Hope that helps.
I want the size of the QTableView to be the same as the table it contains (and fixed) so that it does not have a scrollbar
What you could do is calculate your tableview columns widths according to the data they have (or you can just call resizeColumnToContents for each column to size it to its content). Then change the tableview width to be equal or more then total width of columns + vertical header if shown. You would also need to track model changes and adjust your tableview width + if horizontal header is shown you can track columns resize events and adjust them again. Below is some sample code for this:
initialization:
// add 3 columns to the tableview control
tableModel->insertColumn(0, QModelIndex());
tableModel->insertColumn(1, QModelIndex());
tableModel->insertColumn(2, QModelIndex());
...
// switch off horizonatal scrollbar; though this is not really needed here
ui->tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// adjust size; see code below
adjustTableSize();
// connect to the horizontal header resize event (non needed if header is not shown)
connect(ui->tableView->horizontalHeader(),SIGNAL(sectionResized(int,int,int)), this,
SLOT(updateSectionWidth(int,int,int)));
// connect to the model's datachange event
connect(ui->tableView->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
this, SLOT(dataChanged(QModelIndex,QModelIndex)));
adjust tableview size:
void MainWindow::adjustTableSize()
{
ui->tableView->resizeColumnToContents(0);
ui->tableView->resizeColumnToContents(1);
ui->tableView->resizeColumnToContents(2);
QRect rect = ui->tableView->geometry();
rect.setWidth(2 + ui->tableView->verticalHeader()->width() +
ui->tableView->columnWidth(0) + ui->tableView->columnWidth(1) + ui->tableView->columnWidth(2));
ui->tableView->setGeometry(rect);
}
process model change
void MainWindow::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
adjustTableSize();
}
process horizontal header resize
void MainWindow::updateSectionWidth(int logicalIndex, int, int newSize)
{
adjustTableSize();
}
hope this helps, regards
sum(item.sizeHint()+headeroffset+border) doesn't work well for me, there's probably spacing between the items, even if grid is off. So I made adjustment this way:
view->resizeRowsToContents();
view->resizeColumnsToContents();
QAbstractItemModel* model = view->model();
QHeaderView* horHeader = view->horizontalHeader();
QHeaderView* verHeader = view->verticalHeader();
int rows = model->rowCount();
int cols = model->columnCount();
int x = horHeader->sectionViewportPosition(cols-1) + horHeader->offset()
+ horHeader->sectionSize(cols-1) + 1;
int y = verHeader->sectionViewportPosition(rows-1) + verHeader->offset()
+ verHeader->sectionSize(rows-1) + 1;
QPoint p = view->viewport()->mapToParent(QPoint(x,y));
QRect g = view->geometry();
g.setSize(QSize(p.x(),p.y()));
view->setGeometry(g);
Should work if the last column and last row is visible.
I tried serge_gubenko answer but I didn't work for me (Partly because I wanted to rezise both Height and Width)... so I altered it; To avoid the table being resized by layouts or parent widgets you will need this:
ui->tableView->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed);
Then:
ui->tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->tableView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
QRect rect = ui->tableView->geometry();
int width = 2,length = 2;
for(int col = 0;col<proxySortModel->columnCount();++col){
if(!ui->tableView->isColumnHidden(col))
width += ui->tableView->columnWidth(col);
}
for(int row =0;row<proxySortModel->rowCount();++row)
length += ui->tableView->rowHeight(row);
rect.setWidth(width);
rect.setHeight(length);
ui->tableView->setGeometry(rect);
I hope this helps someone.