QPrintPreviewDialog incorrect preview - qt

Using QPrintPreviewDialog to preview the print, I use the following code
QPrinter printer;
printer.setResolution(QPrinter::HighResolution);
printer.setPaperSize(QPrinter::A4);
printer.setOrientation(QPrinter::Portrait);
QPrintPreviewDialog *pd = new QPrintPreviewDialog(&printer);
connect(pd,SIGNAL(paintRequested(QPrinter*)),this,SLOT(print(QPrinter*)));
pd->exec();
void Class::print(QPrinter *p)
{
QTextEdit *ted = new QTextEdit;
ted->insertHtml("<center><img src='"+QString(":/img/logo.png")+"' width='90' height='72'/><b><font size='9'>Logo Text</font></b></center>");
ted->document()->print(p);
}
On pushing the print button, this dialog appears:
As you can see the content is spread all over the page.
Then I click the page setup button on the preview dialog and this appears:
without changing anything, I click OK and then the preview becomes correct:
The question is that how to correct the preview by code?

Use QTextDocument instead of a QTextEdit, the latter is a widget, which makes the output depend on resizing.

Add a QPageSetupDialog to show before preview.

I had the same issue. Apparently, pressing the OK button of the page setup dialog changes the resolution. To fix this, I change the resolution back in the method which calculates the print preview:
dialog = QPrintPreviewDialog()
dialog.paintRequested.connect(self.print)
dialog.exec_()
def print(self, printer):
printer.setResolution(300)
painter = QPainter()
painter.begin(printer)
...

Related

QAction doesn't show QMenu

I'm creating my UI from Qt Designer and it generares this code:
toolBar = new QToolBar(MainWindow);
QIcon icon;
icon.addFile(QStringLiteral(":/main"), QSize(), QIcon::Normal, QIcon::Off);
MainWindow->addToolBar(Qt::TopToolBarArea, toolBar);
actionConvert = new QAction(MainWindow);
actionConvert->setObjectName(QStringLiteral("actionConvert"));
actionConvert->setIcon(icon);
toolBar->addAction(actionConvert);
Now, back in my frame code:
QMenu *menuAdd = new QMenu (this);
menuAdd->addAction (tr("&Files..."));
menuAdd->addAction (tr("&Directory..."));
ui->actionConvert->setMenu (menuAdd);
When I run the application I can see the qaction in the toolbar even the arrow pointing down, which indicates that there is a menu, but when I click it, the menu doesn't appear...any ideas?
There does not seem to be anything wrong with your example code.
It's possible that the reason you aren't seeing the menu is that you need to press and hold the button for a few seconds in order for the menu to appear. A single click will just execute the button's normal action.
See: QToolButton::ToolButtonPopupMode.
You should add menu with menuBar() method as in my case:
void MainWindow::ueInitMenu()
{
this->ueSetCodeRegisterPlacesAction(new QAction(tr("Places"),
this));
this->ueCodeRegisterPlacesAction()->setShortcut(tr("Ctrl+P"));
this->ueCodeRegisterPlacesAction()->setStatusTip(tr("Shows places code register"));
connect(this->ueCodeRegisterPlacesAction(),
SIGNAL(triggered()),
this,
SLOT(ueSlotShowPlacesView()));
this->ueSetCodeRegisterMenu(this->menuBar()->addMenu(tr("Code register")));
this->ueCodeRegisterMenu()->addAction(this->ueCodeRegisterPlacesAction());
} // ueInitMenu
especialy the line:
this->ueSetCodeRegisterMenu(this->menuBar()->addMenu(tr("Code register")));
so in your case:
this->menuBar()->addMenu(tr("System menu");
and then add actions. Also take a look at Menus Example.

How to cancel out of QColorDialog::getColor()?

In a QT application I am working on, we let the user pick a color using QColorDialog::getColor(). Based on an external event, I need to cancel this opened dialog. Is there a way to do it? I didn't see any other static method on QColorDialog to exit out of the dialog.
Or, may be a better method would be to close all opened dialogs. Is there such a method?
Following this Qt Forum post,
http://www.qtforum.org/article/37032/ok-cancel-buttons-on-qcolordialog.html
I tested the following code.
QColor color = QColorDialog::getColor();
if (!color.isValid()) return;
// Your process for selected color
// ...
and it properly worked for me.
Here is the code which you call by QColorDialog::getColor:
QColorDialog dlg(parent);
if (!title.isEmpty())
dlg.setWindowTitle(title);
dlg.setOptions(options);
dlg.setCurrentColor(initial);
dlg.exec();
return dlg.selectedColor();
As you can see it creates an instance of QColorDialog of stack, sets its initial properties, shows it and returns the result. You can use the same code to create the dialog BUT pay attention on how the dialog is shown.
Method QDialog::exec creates a new event loop (http://qt-project.org/doc/qt-4.8/qeventloop.html) and don't return until the dialog is closed.
That's why you can't call any method of QDialog. Thus QDialog::exec creates so called modal window (http://qt-project.org/doc/qt-4.8/qwidget.html#windowModality-prop).
Solution
To be able to interact with the dialog you need to create it using operator new and use method QDialog::show to show the dialog. But this method returns control immediately when the dialog is shown. So you won't be able to get the color in the next line of your code. Instead you need to subscribe to the dialog signals accepted and rejected, process the results (dialog->currentColor()) and delete the dialog object.
Also you've asked about a way to close all opened dialog. Supposing that all you dialogs are inherited from QDialog:
foreach (QWidget *widget, QApplication::topLevelWidgets()) {
if (QDialog* dialog = qobject_cast<QDialog*>(widget))
dialog->close();
}
This works for me:
QColorDialog *dialog = new QColorDialog(this);
dialog->show();
QObject::connect(dialog,&QDialog::accepted,[=](){
QColor color = dialog->currentColor();
QVariant variant = color;
QString rgb= variant.toString();
ui->eg->setStyleSheet("QLabel { color :"+rgb+" ; }");});`
I hope It helps someone! The above works to change the QLabel font and/or frame but u can try different stylesheets i.e
ui->label->setStyleSheet("QLabel { background-color :"+rgb+" ; color : white; }");
You can not do this when using the static getColor() function.
Construct a dialog object instead so you get a pointer allowing you to call all available functions (like reject() or close()).

How to NOT hide taskbar item during using hide()

When I do hide() on my window, it hides but with taskbar icon. I want to skip hiding tray icon to let me restore it by clicking on it. Is it possible? I don't want use minimize.
user push button -> window hide but he has icons on taskbar (and maybe on systray) and now he can restore it by clicking on taskbar item (or maybe tray icon). I know how to do this working with trayicon but can't get how to stop from hiding taskbar item and all i find is "How to hide taskbar item?".
thanks
ShowMinimised() does exactly what your asking for
however if this doesnt work because of some function you have overridden then provide a code sample please
I found solution:
Maybe someone will need this someday in problems with restore from minimizing using frameless window
void MainWindow::changeEvent( QEvent* e )
{
if( e->type() == QEvent::WindowStateChange)
{
if(this->windowState() & Qt::WindowMinimized )
{
//do something after minimize
}
else
{
setWindowFlags(Qt::Window); //show normal window
setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint);
//and again frameless. somethign like refreshing frameless windows after minimize
this->showNormal();
}
}
}

speeding up initial display of contextMenu?

Environment: Qt 5.1 OSX 10.7.5
I am showing a contextMenu when a Qt::RightButton event is received.
Issue: It works fine except that the initial display is very slow and can take 3-5 seconds to display the menu. Any subsequent displays are immediate. The delay is long enough so that the user can think nothing is happening.
Question: Is there any way to preload or otherwise speed up the initial display of the contextMenu?
I've tried initializing it in my class constructor:
contextMenu = new QMenu(this);
QAction *saveAction=contextMenu->addAction("Save");
connect(saveAction,SIGNAL(triggered()),this,SLOT(saveSlot()));
I've tried declaring it as a pointer and as a... (not pointer? ;-)
QMenu *contextMenu;
This is the mousePressEvent that executes to show the contextMenu.
void RPImageLabel::mousePressEvent(QMouseEvent *event)
{
if (!imageRect.contains(event->pos())) return;
origin = event->pos();
this->setFocus();
if (event->button()==Qt::RightButton){
if (selectionRect.contains(origin))
// contextMenu.exec(this->mapToGlobal(origin));
contextMenu->exec(this->mapToGlobal(origin));
} else {
selectionStarted=true;
selectionRect.setTopLeft(origin);
selectionRect.setBottomRight(origin);
if (rubberBand->isHidden()){
rubberBand->setGeometry(QRect(origin, origin));
rubberBand->show();
repaint();
}
}
}
Ok, I solved this by changing the contextMenuPolicy from DefaultContextMenu to ActionsContextMenu for the widget in Qt Creator.
I'm new to Qt so just guessing here but perhaps this uses a Qt contextMenu instead of the OSX menu? In any event, it displays immediately now. However it does throw an alert on certain conditions:
QNSView mouseDragged:
Internal mouse button tracking invalid (missing Qt::LeftButton)
Not clear what is going on but I see that there has been a bug report filed which may be related.

QWebView reimp. contextMenuEvent(QContextMenuEvent*)

I've reimp. QWebView::contextMenuEvent(QContextMenuEvent*) and it takes no effect on right click on the widget.
Here is my code:
void ExtendedWebView::contextMenuEvent(QContextMenuEvent *event)
{
qDebug() << "called";
m_copyAction->setEnabled(!selectedHtml().isEmpty());
m_contextMenu->setVisible(true);
m_contextMenu->exec(event->globalPos());
}
When I make right-click on the widget, it takes no effect - no menu is shown. What am I doing wrong?
UPD: http://paste.kde.org/640508/ - full code
The current version of Marble's PopupItem where this QWebView is running in does not forward the contextMenuEvent. Change its eventFilter to do that and you'll receive the event.

Resources