Qt wiki will be updated on October 12th 2023 starting at 11:30 AM (EEST) and the maintenance will last around 2-3 hours. During the maintenance the site will be unavailable.
Technical FAQ: Difference between revisions
(→My custom widget appears as a grey rectangle in Designer. How can I fix this ?: Decode HTML entity numbers) |
(Use <syntaxhighlight> instead of <code>) |
||
(8 intermediate revisions by 8 users not shown) | |||
Line 1: | Line 1: | ||
[[Category:Developing with Qt]] | |||
{{LangSwitch}} | {{LangSwitch}} | ||
This page contains technical FAQs. The FAQs have accumulated over a long time period and some of the content may not apply to the latest releases. Please be aware of this when you apply them to the latest builds of Qt. | This page contains technical FAQs. The FAQs have accumulated over a long time period and some of the content may not apply to the latest releases. Please be aware of this when you apply them to the latest builds of Qt. | ||
{| align="right" | {| align="right" | ||
Line 8: | Line 9: | ||
===When to use QPluginLoader vs QLibrary when splitting code into several dlls?=== | ===When to use QPluginLoader vs QLibrary when splitting code into several dlls?=== | ||
QPluginLoader http://doc.qt.io/qt-5 | QPluginLoader http://doc.qt.io/qt-5/qpluginloader.html offers an advantage over QLibrary http://doc.qt.io/qt-5/qlibrary.html because it checks that the plugin is linked against the same version of Qt as the application. QLibrary will not do this check for you. If the library is Qt based and only used within a Qt application then this is probably the best approach. See the documentation http://doc.qt.io/qt-5/plugins-howto.html on how to create plugins. | ||
If you want to make the dlls usable with other applications, then you will need to use QLibrary and create the library as a normal C++ library. | If you want to make the dlls usable with other applications, then you will need to use QLibrary and create the library as a normal C++ library. | ||
Line 16: | Line 17: | ||
Finally, in order to break up your code into several dll's, you could simply create shared libraries that you link against, see: | Finally, in order to break up your code into several dll's, you could simply create shared libraries that you link against, see: | ||
http://doc.qt.io/sharedlibrary | http://doc.qt.io/qt-5/sharedlibrary.html | ||
===What is the process for contributing to Qt?=== | ===What is the process for contributing to Qt?=== | ||
Line 25: | Line 26: | ||
There are a two basic methods for calling a function from one thread on a QObject in another thread. | There are a two basic methods for calling a function from one thread on a QObject in another thread. | ||
* The most basic operation is to post an event to the object in the other thread. The event loop in the target objects thread will then deliver the event to the target object. See the documentation http://doc.qt.io/qt-5/threads-qobject.html#per-thread-event-loop. | * The most basic operation is to post an event to the object in the other thread. The event loop in the target objects thread will then deliver the event to the target object. See the documentation http://doc.qt.io/qt-5/threads-qobject.html#per-thread-event-loop. | ||
* The second approach is to make use of Qt's queued connections. This is also implemented in terms of the first method, and works for any target object that has an event loop running in the thread that owns it. One can either specify a queued connection by passing the parameter Qt::QueuedConnection http://doc.qt.io/qt-5 | * The second approach is to make use of Qt's queued connections. This is also implemented in terms of the first method, and works for any target object that has an event loop running in the thread that owns it. One can either specify a queued connection by passing the parameter Qt::QueuedConnection http://doc.qt.io/qt-5/qt.html#ConnectionType-enum to the connect statement or use Qt::AutoConnection, the default, which decides at runtime how the slot should be called. See the documentation http://doc.qt.io/qt-5/threads-qobject.html#signals-and-slots-across-threads | ||
===How can I rotate items in a QGraphicsView using the mouse?=== | ===How can I rotate items in a QGraphicsView using the mouse?=== | ||
Line 34: | Line 35: | ||
The example below illustrates how this can be done: | The example below illustrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class GraphicsEllipseItem : public QGraphicsEllipseItem | class GraphicsEllipseItem : public QGraphicsEllipseItem | ||
Line 41: | Line 42: | ||
public: | public: | ||
GraphicsEllipseItem() | GraphicsEllipseItem() | ||
{ | { | ||
rotation = 0; | rotation = 0; | ||
Line 74: | Line 74: | ||
QPointF initialPos; | QPointF initialPos; | ||
qreal rotation; | qreal rotation; | ||
}; | }; | ||
Line 88: | Line 88: | ||
QRect rectangle2(50, 80, 80, 60); | QRect rectangle2(50, 80, 80, 60); | ||
GraphicsEllipseItem *item1 = new GraphicsEllipseItem(); | GraphicsEllipseItem *item1 = new GraphicsEllipseItem(); | ||
item1->setRect(-40, -30, 80, 60); | item1->setRect(-40, -30, 80, 60); | ||
Line 100: | Line 99: | ||
GraphicsView box; | GraphicsView box; | ||
box.show(); | box.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</syntaxhighlight> | |||
</ | |||
===The Makefile generated by the Qt Eclipse Integration has no 'dist' target. Is it really missing?=== | ===The Makefile generated by the Qt Eclipse Integration has no 'dist' target. Is it really missing?=== | ||
Line 109: | Line 107: | ||
Makefile.Release. You can create an Eclipse Make Target with target 'dist' | Makefile.Release. You can create an Eclipse Make Target with target 'dist' | ||
and build command 'make -f Makefile.Release' to use it from Eclipse. | and build command 'make -f Makefile.Release' to use it from Eclipse. | ||
===Why is Qt released under LGPL?=== | ===Why is Qt released under LGPL?=== | ||
The LGPL license will make it easier for developers to adopt Qt. By spreading | The LGPL license will make it easier for developers to adopt Qt. By spreading | ||
the use of Qt as widely as possible and establishing a robust ecosystem. | the use of Qt as widely as possible and establishing a robust ecosystem. | ||
===How can I make the non-slot and non-property members of an object available to the script engine?=== | ===How can I make the non-slot and non-property members of an object available to the script engine?=== | ||
By default only a QObject's http://doc.qt.io/qt-5 | By default only a QObject's http://doc.qt.io/qt-5/qobject.html signals, slots, properties, and child objects are available to scripts when a QObject is passed to the QScriptEngine's newQObject() http://doc.qt.io/qt-5/qscriptengine.html#newQObject function. | ||
In order to make other members of the class available to the engine you can use one of the following approaches: | In order to make other members of the class available to the engine you can use one of the following approaches: | ||
Line 126: | Line 124: | ||
===How can I trigger the parent widget to resize when its child widget is resized programmatically?=== | ===How can I trigger the parent widget to resize when its child widget is resized programmatically?=== | ||
Line 135: | Line 133: | ||
The following example illustrates how this can be done: | The following example illustrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Label : public QLabel | class Label : public QLabel | ||
{ | { | ||
Q_OBJECT | Q_OBJECT | ||
public: | public: | ||
Label(const QString & text, QWidget * parent) : QLabel(text, parent) | Label(const QString &text, QWidget *parent) : QLabel(text, parent) | ||
{ | { | ||
changeSize = false; | changeSize = false; | ||
setAutoFillBackground(true); | setAutoFillBackground(true); | ||
QPalette pal = palette(); | QPalette pal = palette(); | ||
pal.setColor(QPalette::Window, Qt::red); | pal.setColor(QPalette::Window, Qt::red); | ||
setPalette(pal); | setPalette(pal); | ||
} | } | ||
QSize sizeHint() const | QSize sizeHint() const | ||
{ | { | ||
if(changeSize) { | if(changeSize) { | ||
return QSize(400,400); | return QSize(400, 400); | ||
} else { | } else { | ||
return QLabel::sizeHint(); | return QLabel::sizeHint(); | ||
} | } | ||
} | } | ||
void setChangedSize(bool value) | void setChangedSize(bool value) | ||
{ | { | ||
changeSize = value; | changeSize = value; | ||
} | } | ||
private: | private: | ||
bool changeSize; | bool changeSize; | ||
}; | }; | ||
class Widget : public QWidget | class Widget : public QWidget | ||
{ | { | ||
Q_OBJECT | Q_OBJECT | ||
public: | public: | ||
Widget() | Widget() | ||
{ | { | ||
label = new Label("Hello World", this); | label = new Label("Hello World", this); | ||
QLabel *label2 = new QLabel("Standard label", this); | QLabel *label2 = new QLabel("Standard label", this); | ||
label2->setAutoFillBackground(true); | label2->setAutoFillBackground(true); | ||
QPalette pal = label2->palette(); | QPalette pal = label2->palette(); | ||
pal.setColor(QPalette::Window, Qt::blue); | pal.setColor(QPalette::Window, Qt::blue); | ||
label2->setPalette(pal); | label2->setPalette(pal); | ||
QVBoxLayout *layout = new QVBoxLayout(this); | QVBoxLayout *layout = new QVBoxLayout(this); | ||
layout->addWidget(label); | layout->addWidget(label); | ||
layout->addWidget(label2); | layout->addWidget(label2); | ||
QTimer::singleShot(2000, this, SLOT(testSlot())); | QTimer::singleShot(2000, this, SLOT(testSlot())); | ||
} | } | ||
public slots: | public slots: | ||
void testSlot() | void testSlot() | ||
{ | { | ||
#if 0 | #if 0 | ||
label->setFixedSize(400,400); | label->setFixedSize(400,400); | ||
#else | #else | ||
QSize oldSize = label->size(); | QSize oldSize = label->size(); | ||
label->setChangedSize(true); | label->setChangedSize(true); | ||
if(oldSize.width() < label->sizeHint().width() || | if(oldSize.width() < label->sizeHint().width() || | ||
oldSize.height() < label->sizeHint().height()) { | oldSize.height() < label->sizeHint().height()) { | ||
label->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); | label->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); | ||
label->updateGeometry(); | label->updateGeometry(); | ||
} else { | } else { | ||
label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); | label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); | ||
label->updateGeometry(); | label->updateGeometry(); | ||
} | } | ||
#endif | #endif | ||
} | } | ||
private: | private: | ||
Label *label; | Label *label; | ||
}; | }; | ||
#include "main.moc" | #include "main.moc" | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
Widget widget; | Widget widget; | ||
widget.resize(200,200); | widget.resize(200,200); | ||
widget.show(); | widget.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Assistant does not launch or the documentation does not show up when launching Assistant, what is wrong?=== | ===Assistant does not launch or the documentation does not show up when launching Assistant, what is wrong?=== | ||
Deleting the following Qt Assistant http://doc.qt.io/qt-5 | Deleting the following Qt Assistant http://doc.qt.io/qt-5/assistant-manual.html key in the registry might solve the problem: | ||
*HKEY_CURRENT_USER\SOFTWARE\Trolltech\Qt Assistant* | *HKEY_CURRENT_USER\SOFTWARE\Trolltech\Qt Assistant* | ||
===When I set a font/palette explicitly for a QLabel on the Mac, then it is respected. If my QLabel only inherits the font, then it is ignored. What is the reason for this?=== | ===When I set a font/palette explicitly for a QLabel on the Mac, then it is respected. If my QLabel only inherits the font, then it is ignored. What is the reason for this?=== | ||
Line 231: | Line 229: | ||
When in doubt, set the font or palette directly. | When in doubt, set the font or palette directly. | ||
===How can a menu be removed from a menubar?=== | ===How can a menu be removed from a menubar?=== | ||
You can remove actions from the menubar using QWidget::removeAction() http://doc.qt.io/qt-5/qwidget.html#removeAction. | You can remove actions from the menubar using QWidget::removeAction() http://doc.qt.io/qt-5/qwidget.html#removeAction. | ||
In order to get hold of the action associated with the menu, use QMenu::menuAction() http://doc.qt.io/qt-5/qmenu.html#menuAction | In order to get hold of the action associated with the menu, use QMenu::menuAction() http://doc.qt.io/qt-5/qmenu.html#menuAction | ||
Line 240: | Line 238: | ||
The example below demonstrates how this can be done: | The example below demonstrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class MainWindow : public QMainWindow | class MainWindow : public QMainWindow | ||
{ | { | ||
public: | public: | ||
MainWindow() | MainWindow() | ||
{ | { | ||
QMenu *menu = menuBar()->addMenu("Test"); | QMenu *menu = menuBar()->addMenu("Test"); | ||
QMenu *menu2 = menuBar()->addMenu("Test2"); | QMenu *menu2 = menuBar()->addMenu("Test2"); | ||
menu->addAction("First"); | menu->addAction("First"); | ||
menu2->addAction("Second"); | menu2->addAction("Second"); | ||
menuBar()->removeAction(menu->menuAction()); | menuBar()->removeAction(menu->menuAction()); | ||
} | } | ||
}; | }; | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
MainWindow box; | MainWindow box; | ||
box.show(); | box.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I get/set the max length of a QTextEdit ?=== | ===How can I get/set the max length of a QTextEdit ?=== | ||
There is no direct API to set/get a maximum length of a QTextEdit, but you can handle this yourself by connecting a slot to the contentsChanged() http://doc.qt.io/qt-5/qtextdocument.html#contentsChanged signal and then call toPlainText().length() http://doc.qt.io/qt-5/qtextdocument.html#toPlainText to find out how big it is. If it is up to the limit then you can reimplement keyPressEvent() http://doc.qt.io/qt-5 | There is no direct API to set/get a maximum length of a QTextEdit, but you can handle this yourself by connecting a slot to the contentsChanged() http://doc.qt.io/qt-5/qtextdocument.html#contentsChanged signal and then call toPlainText().length() http://doc.qt.io/qt-5/qtextdocument.html#toPlainText to find out how big it is. If it is up to the limit then you can reimplement keyPressEvent() http://doc.qt.io/qt-5/qtextedit.html#keyPressEvent and keyReleaseEvent() http://doc.qt.io/qt-5/qtextedit.html#keyReleaseEvent to do nothing for normal characters. | ||
Line 272: | Line 271: | ||
===Lines with width 1 disappear when not using anti-aliasing=== | ===Lines with width 1 disappear when not using anti-aliasing=== | ||
When having a transformation set and not using anti-aliasing then if you draw something that's smaller than a pixel, you are not guaranteed that it will get drawn. In order to guarantee that it shows up you need to either turn on anti-aliasing or draw using a cosmetic pen. | When having a transformation set and not using anti-aliasing then if you draw something that's smaller than a pixel, you are not guaranteed that it will get drawn. In order to guarantee that it shows up you need to either turn on anti-aliasing or draw using a cosmetic pen. | ||
===Should one use qApp or QCoreApplication::instance() when referring to the application object?=== | ===Should one use qApp or QCoreApplication::instance() when referring to the application object?=== | ||
It does not matter which one you use. The instance() http://doc.qt.io/qt-5 | It does not matter which one you use. The instance() http://doc.qt.io/qt-5/qcoreapplication.html#instance function was added since many feel using a function and not a global variable is more elegant, qApp http://doc.qt.io/qt-5/qapplication.html#qApp is kept for compatibility reasons and for those who prefer global pointers | ||
===When keeping a key pressed down, then I receive a number of keyReleaseEvents() in addition to keyPressEvents(). Why is this happening and what can be done to only get a mousePressEvent() ?=== | |||
# | When a given key is continuously pressed it results in a continuous stream of events for the associated key. You will get both keyPressEvents() http://doc.qt.io/qt-5/qwidget.html#keyPressEvent and keyReleaseEvents() http://doc.qt.io/qt-5/qwidget.html#keyReleaseEvent for the relevant key even if you have not released the key. You can not stop the events from being sent since they come directly from the windowing system. What you can do however is to check the autoRepeat() http://doc.qt.io/qt-5/qkeyevent.html#isAutoRepeat function in your key event handler and just ignore the key event if it was generated by an auto-repeating key. | ||
# | |||
See the following example for an illustration: | |||
<syntaxhighlight lang="cpp"> | |||
#include <QtWidgets> | |||
#include < | |||
class Widget : public QWidget | class Widget : public QWidget | ||
{ | { | ||
public: | public: | ||
Widget() | Widget() | ||
{ | { | ||
setFocusPolicy(Qt::StrongFocus); | setFocusPolicy(Qt::StrongFocus); | ||
} | } | ||
void keyPressEvent(QKeyEvent *event) | void keyPressEvent(QKeyEvent *event) | ||
{ | { | ||
if(event->isAutoRepeat() ) { | if (event->isAutoRepeat()) { | ||
qDebug() << "keyPressEvent ignore"; | qDebug() << "keyPressEvent ignore"; | ||
event->ignore(); | event->ignore(); | ||
} else { | } else { | ||
qDebug() << "keyPressEvent accept"; | qDebug() << "keyPressEvent accept"; | ||
event->accept(); | event->accept(); | ||
} | } | ||
} | } | ||
void keyReleaseEvent(QKeyEvent *event) | void keyReleaseEvent(QKeyEvent *event) | ||
{ | { | ||
if(event->isAutoRepeat() ) { | if (event->isAutoRepeat()) { | ||
qDebug() << "keyReleaseEvent ignore"; | qDebug() << "keyReleaseEvent ignore"; | ||
event->ignore(); | event->ignore(); | ||
} else { | } else { | ||
qDebug() << "keyReleaseEvent accept"; | qDebug() << "keyReleaseEvent accept"; | ||
event->accept(); | event->accept(); | ||
} | } | ||
} | } | ||
}; | }; | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
Widget box; | Widget box; | ||
box.show(); | box.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I | ===How can I capture events for the delegate in my own class?=== | ||
You | It is not possible to capture events for the delegate in a custom class. You need to reimplement the eventFilter() http://doc.qt.io/qt-5/qstyleditemdelegate.html#eventFilter for the delegate in order to grab its events. This is necessary because the delegate installs an event filter on the editor for the cell after the external event filter is installed, meaning it is always going to get the event first. | ||
===How can I ensure that a horizontal scrollbar and not an ellipse shows up when resizing a column smaller than its content in a QTreeView ?=== | ===How can I ensure that a horizontal scrollbar and not an ellipse shows up when resizing a column smaller than its content in a QTreeView ?=== | ||
To ensure that a scrollbar shows up instead of an ellipse when resizing a column smaller than its content in a QTreeView http://doc.qt.io/qt-5 | To ensure that a scrollbar shows up instead of an ellipse when resizing a column smaller than its content in a QTreeView http://doc.qt.io/qt-5/qtreeview.html, then you need to call | ||
< | <syntaxhighlight lang="cpp"> | ||
setResizeMode(relevantColumn, QHeaderView::ResizeToContents) </ | setResizeMode(relevantColumn, QHeaderView::ResizeToContents) </syntaxhighlight> | ||
on the header of your tree, so that the section is resized to its optimal size. You also need to call | on the header of your tree, so that the section is resized to its optimal size. You also need to call | ||
< | <syntaxhighlight lang="cpp">setStretchLastSection(false) </syntaxhighlight> | ||
if your tree only contains one column. | if your tree only contains one column. | ||
Line 422: | Line 351: | ||
See the following example for a demonstration: | See the following example for a demonstration: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
QTreeWidget tree; | QTreeWidget tree; | ||
tree.setColumnCount(1); | tree.setColumnCount(1); | ||
tree. | tree.setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); | ||
tree.header()-> | tree.header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); | ||
tree.header()->setStretchLastSection(false); | tree.header()->setStretchLastSection(false); | ||
QStringList list | QStringList list = {"An item in a QTreeWidget with some text"}; | ||
QTreeWidgetItem *item = new QTreeWidgetItem(&tree, list); | QTreeWidgetItem *item = new QTreeWidgetItem(&tree, list); | ||
tree.show(); | tree.show(); | ||
return | return | ||
}</ | }</syntaxhighlight> | ||
===Why doesn't Eclipse know about some of Qt's symbols / class names?=== | ===Why doesn't Eclipse know about some of Qt's symbols / class names?=== | ||
Line 452: | Line 381: | ||
You probably also want to run Eclipse with a higher memory limit, so call eclipse from the command line, with e.g.: | You probably also want to run Eclipse with a higher memory limit, so call eclipse from the command line, with e.g.: | ||
< | <syntaxhighlight>eclipse -vmargs -Xmx1000M</syntaxhighlight> | ||
===Does Qt provide an API for opening/saving encrypted files?=== | ===Does Qt provide an API for opening/saving encrypted files?=== | ||
Qt does not offer encryption for opening/saving files, you will need to use a 3rd party library to manage this. | Qt does not offer encryption for opening/saving files, you will need to use a 3rd party library to manage this. | ||
===Example of how to style QToolBox with QStyle=== | ===Example of how to style QToolBox with QStyle=== | ||
The following is an sample subclass of QWindowsXPStyle() http://doc.qt.io/qt-5 | The following is an sample subclass of QWindowsXPStyle() http://doc.qt.io/qt-5/qwindowsxpstyle.html to show how a QToolBox http://doc.qt.io/qt-5/qtoolbox.html can be styled. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class MyStyle : public QWindowsXPStyle | class MyStyle : public QWindowsXPStyle | ||
Line 469: | Line 398: | ||
public: | public: | ||
MyStyle() : QWindowsXPStyle() {} | MyStyle() : QWindowsXPStyle() {} | ||
void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, | void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, | ||
const QWidget *widget = | const QWidget *widget = nullptr) const override | ||
{ | { | ||
if (element == CE_ToolBoxTab) { | if (element == CE_ToolBoxTab) { | ||
Line 497: | Line 426: | ||
return a.exec(); | return a.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can we create a binary on Leopard that runs on both 10.4 and 10.5?=== | ===How can we create a binary on Leopard that runs on both 10.4 and 10.5?=== | ||
When creating an application on Leopard , then in order for the application to run on both 10.4 and 10.5 then you need to set the *QMAKE_MACOSX_DEPLOYMENT_TARGET* to 10.4 in your .pro file as follows: | When creating an application on Leopard , then in order for the application to run on both 10.4 and 10.5 then you need to set the *QMAKE_MACOSX_DEPLOYMENT_TARGET* to 10.4 in your .pro file as follows: | ||
< | <syntaxhighlight> QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4 | ||
</ | </syntaxhighlight> | ||
This is documented here http://doc.qt.io/qt-5/deployment-mac.html#mac-os-x-version-dependencies. | This is documented here http://doc.qt.io/qt-5/deployment-mac.html#mac-os-x-version-dependencies. | ||
Line 510: | Line 439: | ||
Note that if you are using native calls then you will have to add checks yourself to ensure that it works correctly for all versions of the operating system. You can for example use | Note that if you are using native calls then you will have to add checks yourself to ensure that it works correctly for all versions of the operating system. You can for example use | ||
< | <syntaxhighlight lang="cpp"> QSysInfo::MacintoshVersion < QsysInfo::MV_10_5</syntaxhighlight> | ||
or check if the function pointer is non-zero. This will not be necessary when only using the Qt API as Qt does such checks for you. | or check if the function pointer is non-zero. This will not be necessary when only using the Qt API as Qt does such checks for you. | ||
Note that a Qt application compiled against 10.4 should run fine on 10.5. | Note that a Qt application compiled against 10.4 should run fine on 10.5. | ||
===My Windows build of Qt stops and complains that one of the plugins can't be opened. What's wrong ?=== | ===My Windows build of Qt stops and complains that one of the plugins can't be opened. What's wrong ?=== | ||
Line 523: | Line 452: | ||
the build. If this does not help, then try deleting the plugin dll explicitly | the build. If this does not help, then try deleting the plugin dll explicitly | ||
and restart the build. This should solve the problem. | and restart the build. This should solve the problem. | ||
===How can I prevent the text in a QComboBox's dropdown from being clipped when the QComboBox is smaller than the text?=== | ===How can I prevent the text in a QComboBox's dropdown from being clipped when the QComboBox is smaller than the text?=== | ||
To ensure that the text in the QComboBox's http://doc.qt.io/qt-5 | To ensure that the text in the QComboBox's http://doc.qt.io/qt-5/qcombobox.html view does not get clipped when the QComboBox is resized to a smaller width than the width of the text in the view, you can call | ||
< | <syntaxhighlight lang="cpp"> | ||
view->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); | view->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); | ||
</ | </syntaxhighlight> | ||
which stops the view from being smaller than its sizeHint() http://doc.qt.io/qt-5 | which stops the view from being smaller than its sizeHint() http://doc.qt.io/qt-5/qcombobox.html#sizeHint. See the documentation on size policies http://doc.qt.io/qt-5/qsizepolicy.html#Policy-enum. | ||
See the following example for a demonstration: | See the following example for a demonstration: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class MyWidget : public QWidget | class MyWidget : public QWidget | ||
{ | { | ||
public: | public: | ||
MyWidget(QWidget *parent) : QWidget(parent) | |||
{ | |||
QVBoxLayout *layout = new QVBoxLayout(this); | |||
QComboBox *combo = new QComboBox(this); | |||
combo->view()->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); | |||
layout->addWidget(combo, 1, 0); | |||
combo->addItem(Combo box entry number 1); | |||
combo->addItem(Combo box entry number 2); | |||
combo->addItem(Combo box entry number 3); | |||
setMinimumWidth(5); | |||
} | |||
}; | }; | ||
int main( int argc, char **argv ) | int main( int argc, char **argv ) | ||
{ | { | ||
QApplication app( argc, argv ); | |||
MyWidget mw(0); | |||
mw.show(); | |||
return app.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
===Why does the 'New C++ Class' wizard miss most of the Qt classes in the 'Base Classes' list?=== | ===Why does the 'New C++ Class' wizard miss most of the Qt classes in the 'Base Classes' list?=== | ||
Line 571: | Line 500: | ||
header files, or check the 'Index all files' checkbox in the global or project | header files, or check the 'Index all files' checkbox in the global or project | ||
specific 'Indexer' settings (CDT 4.0 only). | specific 'Indexer' settings (CDT 4.0 only). | ||
===How can I sort a QComboBox?=== | ===How can I sort a QComboBox?=== | ||
Line 579: | Line 508: | ||
===Which compiler and debugger can I use with the Eclipse C++ Integration on Windows?=== | ===Which compiler and debugger can I use with the Eclipse C++ Integration on Windows?=== | ||
Line 587: | Line 516: | ||
debug in Eclipse. For cl.exe it is possible to build release and debug | debug in Eclipse. For cl.exe it is possible to build release and debug | ||
versions in Eclipse, but it will not be possible to debug it. | versions in Eclipse, but it will not be possible to debug it. | ||
===When using fromWinHBITMAP() to create my pixmaps, they appear with a black background. What's wrong ?=== | ===When using fromWinHBITMAP() to create my pixmaps, they appear with a black background. What's wrong ?=== | ||
If you pass in QPixmap::NoAlpha http://doc.qt.io/qt-5 | If you pass in QPixmap::NoAlpha http://doc.qt.io/qt-5/qpixmap.html#HBitmapFormat-enum as the format to fromWinHBITMAP() http://doc.qt.io/qt-5/qpixmap.html#fromWinHBITMAP then all pixels with transparency will have an undefined value, for instance black. | ||
If the format you pass in to fromWinHBITMAP() is QPixmap::PremultipliedAlpha option the pixel data must be in a premultiplied alpha format, otherwise the results will be undefined. QPixmap expects opaque pixels to be in the form 0xFFrrggbb, where the alpha byte is set to 255. If your pixels are in the form 0x00rrggbb, having an alpha of 0 then the image will not look correct. | If the format you pass in to fromWinHBITMAP() is QPixmap::PremultipliedAlpha option the pixel data must be in a premultiplied alpha format, otherwise the results will be undefined. QPixmap expects opaque pixels to be in the form 0xFFrrggbb, where the alpha byte is set to 255. If your pixels are in the form 0x00rrggbb, having an alpha of 0 then the image will not look correct. | ||
If you created your pixel data using GDI functions its likely that you ended up with pixels in the form 0x00rrggbb as GDI will unset the alpha channel of all pixels it touches. You can work around this by manually patching up the alpha channel, afterwards or by only using GDI functions that support a proper alpha channel, like AlphaBlend. | If you created your pixel data using GDI functions its likely that you ended up with pixels in the form 0x00rrggbb as GDI will unset the alpha channel of all pixels it touches. You can work around this by manually patching up the alpha channel, afterwards or by only using GDI functions that support a proper alpha channel, like AlphaBlend. | ||
===Is it possible to have transparent Qt widgets on top of a | |||
===Is it possible to have transparent Qt widgets on top of a QOpenGLWidget?=== | |||
Qt provides a way to paint to an OpenGL context, but this is in the end | Qt provides a way to paint to an OpenGL context, but this is in the end | ||
painted separately from Qt and the two painting systems are not synchronized, | painted separately from Qt and the two painting systems are not synchronized, | ||
so Qt cannot compose (semi-)transparent images on top of a | so Qt cannot compose (semi-)transparent images on top of a QOpenGLWidget. At best, | ||
you can have opaque widgets on top of the | you can have opaque widgets on top of the QOpenGLWidget, but even then you may | ||
experience some flicker due to the painting being asynchronous. | experience some flicker due to the painting being asynchronous. | ||
===Where do I find the resource editor in the integrated Qt Designer when using the Qt Eclipse Integration?=== | ===Where do I find the resource editor in the integrated Qt Designer when using the Qt Eclipse Integration?=== | ||
Line 609: | Line 538: | ||
double click on the resource file in the Projects view. The integrated Qt | double click on the resource file in the Projects view. The integrated Qt | ||
Designer doesn't come with an extra resource editor. | Designer doesn't come with an extra resource editor. | ||
===Is there a way to make a menu in a QMainWindow that automatically redirects standard commands to the current widget ?=== | ===Is there a way to make a menu in a QMainWindow that automatically redirects standard commands to the current widget ?=== | ||
There is no automatic way to redirect the commands in a QMainWindow's http://doc.qt.io/qt-5 | There is no automatic way to redirect the commands in a QMainWindow's http://doc.qt.io/qt-5/qmainwindow.html menu to the current widget. If you would like e.g the Copy command to be redirected to the current widget, then you can listen for the QApplication::focusChanged() http://doc.qt.io/qt-5/qapplication.html#focusChanged signal and connect that signal to a slot which determines which actions should be executed for the current widget. | ||
===How do I find out why my mouse and keyboard work in QVFb, but not on my target system?=== | ===How do I find out why my mouse and keyboard work in QVFb, but not on my target system?=== | ||
Line 623: | Line 552: | ||
To debug on the Linux frame buffer, run the application in a console on your | To debug on the Linux frame buffer, run the application in a console on your | ||
desktop system, with the option: -display LinuxFb instead of -display QVFb. | desktop system, with the option: -display LinuxFb instead of -display QVFb. | ||
===How can I specify the spacing between the text and the icon for an item in a view?=== | ===How can I specify the spacing between the text and the icon for an item in a view?=== | ||
In order to specify the margin between the decoration and the text for an item in a view, you can subclass the style and reimplement pixelMetric() http://doc.qt.io/qt-5 | In order to specify the margin between the decoration and the text for an item in a view, you can subclass the style and reimplement pixelMetric() http://doc.qt.io/qt-5/qstyle.html#pixelMetric to return the value you want for PM_FocusFrameHMargin http://doc.qt.io/qt-5/qstyle.html#PixelMetric-enum and/or PM_FocusFrameVMargin. Alternatively, you can reimplement paint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#paint for the item delegate to draw the margins as you want. | ||
The following example demonstrates how this can be done by reimplementing pixelMetric(): | The following example demonstrates how this can be done by reimplementing pixelMetric(): | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Style: public QWindowsStyle | class Style: public QWindowsStyle | ||
{ | { | ||
public: | public: | ||
Style() {} | Style() {} | ||
int pixelMetric(PixelMetric metric, const QStyleOption *option = | int pixelMetric(PixelMetric metric, const QStyleOption *option = nullptr, | ||
const QWidget *widget = | const QWidget *widget = nullptr) const override | ||
{ | { | ||
if (metric == PM_FocusFrameHMargin) { | if (metric == PM_FocusFrameHMargin) { | ||
return 10; | return 10; | ||
} else { | } else { | ||
return QWindowsStyle::pixelMetric(metric, option, widget); | return QWindowsStyle::pixelMetric(metric, option, widget); | ||
} | } | ||
} | } | ||
}; | }; | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
QTreeWidget tree; | QTreeWidget tree; | ||
tree.setStyle(new Style()); | tree.setStyle(new Style()); | ||
QPixmap pix(12, 12); | QPixmap pix(12, 12); | ||
pix.fill(Qt::red); | pix.fill(Qt::red); | ||
QTreeWidgetItem *item1 = new QTreeWidgetItem(&tree); | QTreeWidgetItem *item1 = new QTreeWidgetItem(&tree); | ||
item1->setText(0, "first"); | item1->setText(0, "first"); | ||
item1->setIcon(0, QIcon(pix)); | item1->setIcon(0, QIcon(pix)); | ||
QTreeWidgetItem *item2 = new QTreeWidgetItem(&tree); | QTreeWidgetItem *item2 = new QTreeWidgetItem(&tree); | ||
item2->setText(0, "second"); | item2->setText(0, "second"); | ||
item2->setIcon(0, QIcon(pix)); | item2->setIcon(0, QIcon(pix)); | ||
tree.show(); | tree.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Does qmake have support for pkg-config?=== | ===Does qmake have support for pkg-config?=== | ||
Yes, simply add link_pkgconfig to the CONFIG entry in your .pro file and then add pkg-config configurations to the PKGCONFIG variable, e.g: | Yes, simply add link_pkgconfig to the CONFIG entry in your .pro file and then add pkg-config configurations to the PKGCONFIG variable, e.g: | ||
< | <syntaxhighlight>CONFIG +=link_pkgconfig | ||
TEMPLATE = app | TEMPLATE = app | ||
TARGET = | TARGET = | ||
Line 677: | Line 606: | ||
# Input | # Input | ||
SOURCES += main.cpp</ | SOURCES += main.cpp</syntaxhighlight> | ||
See the documentation http://doc.qt.io/qt-5/qmake-project-files.html#configuration-features. | See the documentation http://doc.qt.io/qt-5/qmake-project-files.html#configuration-features. | ||
===How can I align the text and icons in an itemview?=== | ===How can I align the text and icons in an itemview?=== | ||
You can align the text and icons in your itemview by subclassing the itemview and reimplementing viewOptions() http://doc.qt.io/qt-5/qabstractitemview.html#viewOptions to return the alignment you want for the QStyleOptionViewItem http://doc.qt.io/qt-5 | You can align the text and icons in your itemview by subclassing the itemview and reimplementing viewOptions() http://doc.qt.io/qt-5/qabstractitemview.html#viewOptions to return the alignment you want for the QStyleOptionViewItem http://doc.qt.io/qt-5/qstyleoptionviewitem.html. | ||
The example below demonstrates how this can be done. | The example below demonstrates how this can be done. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class ListWidget : public QListWidget | class ListWidget : public QListWidget | ||
{ | { | ||
public: | public: | ||
ListWidget() | ListWidget() | ||
{ | { | ||
QListWidgetItem *item1 = new QListWidgetItem("one"); | QListWidgetItem *item1 = new QListWidgetItem("one"); | ||
QListWidgetItem *item2 = new QListWidgetItem("two"); | QListWidgetItem *item2 = new QListWidgetItem("two"); | ||
QListWidgetItem *item3 = new QListWidgetItem("three"); | QListWidgetItem *item3 = new QListWidgetItem("three"); | ||
addItem(item1); | addItem(item1); | ||
addItem(item2); | addItem(item2); | ||
addItem(item3); | addItem(item3); | ||
} | } | ||
QStyleOptionViewItem viewOptions() const | QStyleOptionViewItem viewOptions() const override | ||
{ | { | ||
QStyleOptionViewItem item; | QStyleOptionViewItem item; | ||
item.init(this); | item.init(this); | ||
item.displayAlignment = Qt::AlignRight; | item.displayAlignment = Qt::AlignRight; | ||
return item; | return item; | ||
} | } | ||
}; | }; | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
ListWidget listWidget; | ListWidget listWidget; | ||
listWidget.show(); | listWidget.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I change the margins of my QTextDocument?=== | ===How can I change the margins of my QTextDocument?=== | ||
Line 730: | Line 659: | ||
# Then call QTextFrameFormat::setMargin() http://doc.qt.io/qt-5/qtextframeformat.html#setMargin with the desired value. | # Then call QTextFrameFormat::setMargin() http://doc.qt.io/qt-5/qtextframeformat.html#setMargin with the desired value. | ||
In order to specify individual margins (independently) for each block of text, you can use the QTextBlockFormat http://doc.qt.io/qt-5/qtextblockformat.html#setTopMargin set margin functions. | In order to specify individual margins (independently) for each block of text, you can use the QTextBlockFormat http://doc.qt.io/qt-5/qtextblockformat.html#setTopMargin set margin functions. | ||
The example below demonstrates how to set margins for the entire document and also how to set the margins for individual blocks. | The example below demonstrates how to set margins for the entire document and also how to set the margins for individual blocks. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
QTextEdit edit; | QTextEdit edit; | ||
edit.setText("The QTextEdit widget is an advanced editor that supports " | edit.setText("The QTextEdit widget is an advanced editor that supports " | ||
"formatted rich text. "); | "formatted rich text. "); | ||
edit.append("It can be used to display HTML and other rich document formats."); | edit.append("It can be used to display HTML and other rich document formats."); | ||
QTextDocument * doc = edit.document(); | QTextDocument * doc = edit.document(); | ||
QTextCursor cursor(doc); | QTextCursor cursor(doc); | ||
cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); | cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); | ||
//cursor.movePosition(QTextCursor::Start, QTextCursor::KeepAnchor); | //cursor.movePosition(QTextCursor::Start, QTextCursor::KeepAnchor); | ||
#if 1 | #if 1 | ||
QTextBlockFormat tbf = cursor.blockFormat(); | QTextBlockFormat tbf = cursor.blockFormat(); | ||
tbf.setLeftMargin(100); | tbf.setLeftMargin(100); | ||
tbf.setTopMargin(100); | tbf.setTopMargin(100); | ||
cursor.setBlockFormat(tbf); | cursor.setBlockFormat(tbf); | ||
#else | #else | ||
QTextFrame *tf = doc->rootFrame(); | QTextFrame *tf = doc->rootFrame(); | ||
QTextFrameFormat tff = tf->frameFormat(); | QTextFrameFormat tff = tf->frameFormat(); | ||
tff.setMargin(50); | tff.setMargin(50); | ||
tf->setFrameFormat(tff); | tf->setFrameFormat(tff); | ||
#endif | #endif | ||
edit.show(); | edit.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Is is possible to run Qt applications on Windows XP Embedded ?=== | ===Is is possible to run Qt applications on Windows XP Embedded ?=== | ||
Line 768: | Line 697: | ||
XP Embedded and since they are binary compatible, but it is not supported or | XP Embedded and since they are binary compatible, but it is not supported or | ||
tested by us. | tested by us. | ||
===I use a shortcut for interacting with a widget in my QTest::keyClick() function and the test fails. What can be wrong?=== | ===I use a shortcut for interacting with a widget in my QTest::keyClick() function and the test fails. What can be wrong?=== | ||
The problem is likely to be that you have not called show() http://doc.qt.io/qt-5 | The problem is likely to be that you have not called show() http://doc.qt.io/qt-5/qwidget.html#show on your widget. If the widget is not visible, the shortcut does not actually behave correctly. You wouldn't typically have a shortcut that works for a non visible widget, so you should show your widget to get this test to pass. | ||
===How can I change the icon for the sort indicator and its position in a QHeaderView?=== | ===How can I change the icon for the sort indicator and its position in a QHeaderView?=== | ||
In order to change the icon and position for the sort indicator in a QHeaderView http://doc.qt.io/qt-5/qheaderview.html, you can subclass the style and reimplement drawPrimitive() http://doc.qt.io/qt-5/qstyle.html#drawPrimitive to draw the sort indicator using the icon and position you want. | In order to change the icon and position for the sort indicator in a QHeaderView http://doc.qt.io/qt-5/qheaderview.html, you can subclass the style and reimplement drawPrimitive() http://doc.qt.io/qt-5/qstyle.html#drawPrimitive to draw the sort indicator using the icon and position you want. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Style: public QWindowsStyle | class Style: public QWindowsStyle | ||
{ | { | ||
public: | public: | ||
Style () {} | Style () {} | ||
void drawPrimitive(PrimitiveElement element, const QStyleOption *option, | void drawPrimitive(PrimitiveElement element, const QStyleOption *option, | ||
QPainter *painter, const QWidget *widget = | QPainter *painter, const QWidget *widget = nullptr) const | ||
{ | { | ||
if (element == PE_IndicatorHeaderArrow ) { | if (element == PE_IndicatorHeaderArrow ) { | ||
const QStyleOptionHeader *headerOption = | const QStyleOptionHeader *headerOption = | ||
qstyleoption_cast<const QStyleOptionHeader *>(option); | qstyleoption_cast<const QStyleOptionHeader *>(option); | ||
int x, y, width, height; | int x, y, width, height; | ||
option->rect.getRect(&x, &y, &width, &height); | option->rect.getRect(&x, &y, &width, &height); | ||
QPixmap pixmap; | QPixmap pixmap; | ||
if (headerOption->sortIndicator == QStyleOptionHeader::SortUp) | if (headerOption->sortIndicator == QStyleOptionHeader::SortUp) | ||
pixmap.load("arrow_up.png"); | pixmap.load("arrow_up.png"); | ||
else | else | ||
pixmap.load("arrow_down.png"); | pixmap.load("arrow_down.png"); | ||
painter->save(); | painter->save(); | ||
painter->drawPixmap(x+width,y+height,pixmap); | painter->drawPixmap(x+width,y+height,pixmap); | ||
painter->restore(); | painter->restore(); | ||
} else | } else | ||
QWindowsStyle::drawPrimitive(element, option, painter, widget); | QWindowsStyle::drawPrimitive(element, option, painter, widget); | ||
} | } | ||
}; | }; | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
QTableWidget table(2,2); | QTableWidget table(2,2); | ||
QTableWidgetItem *item1 = new QTableWidgetItem("1"); | QTableWidgetItem *item1 = new QTableWidgetItem("1"); | ||
QTableWidgetItem *item2 = new QTableWidgetItem("2"); | QTableWidgetItem *item2 = new QTableWidgetItem("2"); | ||
table.setItem(0,0, item1); | table.setItem(0,0, item1); | ||
table.setItem(1,0, item2); | table.setItem(1,0, item2); | ||
table.setSortingEnabled(true); | table.setSortingEnabled(true); | ||
app.setStyle(new Style()); | app.setStyle(new Style()); | ||
table.show(); | table.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
Alternatively, you can use a stylesheet to achieve this. See the | Alternatively, you can use a stylesheet to achieve this. See the | ||
documentation: | documentation: | ||
http://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qheaderview | http://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qheaderview | ||
===When creating a library with Qt/Windows and using it in an application, then there is a link error regarding symbols which are in the library=== | ===When creating a library with Qt/Windows and using it in an application, then there is a link error regarding symbols which are in the library=== | ||
When seeing errors like the following: | When seeing errors like the following: | ||
< | <syntaxhighlight>MyObj.obj : error LNK2019: unresolved external symbol public: static | ||
struct QMetaObject const MyObj::staticMetaObject" | struct QMetaObject const MyObj::staticMetaObject" | ||
(?staticMetaObject@MyObj@@2UQMetaObject@@B) referenced in function class | (?staticMetaObject@MyObj@@2UQMetaObject@@B) referenced in function class | ||
MyObj * __cdecl qobject_cast<class MyObj *>(class QObject *)" | MyObj * __cdecl qobject_cast<class MyObj *>(class QObject *)" | ||
</ | </syntaxhighlight> | ||
it is probably a result of the linker not finding the symbols from the library. You need to make sure that the symbols in your library are properly exported when the library is created. Subsequently imported when you are linking against the library, so you should have something like the following in a header file in your library: | it is probably a result of the linker not finding the symbols from the library. You need to make sure that the symbols in your library are properly exported when the library is created. Subsequently imported when you are linking against the library, so you should have something like the following in a header file in your library: | ||
< | <syntaxhighlight lang="cpp">#if defined TEST | ||
#define TEST_COMMON_DLLSPEC __declspec(dllexport) | #define TEST_COMMON_DLLSPEC __declspec(dllexport) | ||
#else | #else | ||
#define TEST_COMMON_DLLSPEC __declspec(dllimport) | #define TEST_COMMON_DLLSPEC __declspec(dllimport) | ||
#endif</ | #endif</syntaxhighlight> | ||
Line 848: | Line 777: | ||
< | <syntaxhighlight lang="cpp"> | ||
class TEST_COMMON_DLLSPEC MyObj : public QObject { ... }; | class TEST_COMMON_DLLSPEC MyObj : public QObject { ... }; | ||
</ | </syntaxhighlight> | ||
Then add to your library's .pro file the following line so it knows that the | Then add to your library's .pro file the following line so it knows that the | ||
symbols need to be exported in this case: | symbols need to be exported in this case: | ||
< | <syntaxhighlight> DEFINES += TEST | ||
</ | </syntaxhighlight> | ||
See the following wiki page http://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application for more information and a complete example. | See the following wiki page http://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application for more information and a complete example. | ||
Line 867: | Line 796: | ||
To enable Edit & Continue in your .pro file, add the following to the .pro file: | To enable Edit & Continue in your .pro file, add the following to the .pro file: | ||
< | <syntaxhighlight>QMAKE_CFLAGS_DEBUG += -ZI | ||
QMAKE_CXXFLAGS_DEBUG += -ZI </ | QMAKE_CXXFLAGS_DEBUG += -ZI </syntaxhighlight> | ||
Alternatively, you can enable Edit & Continue for your project inside Visual Studio, as follows: | Alternatively, you can enable Edit & Continue for your project inside Visual Studio, as follows: | ||
Line 875: | Line 804: | ||
* select C/C++ -> General" | * select C/C++ -> General" | ||
* set Debug Information Format to Program Database for Edit & Continue (/ZI)" | * set Debug Information Format to Program Database for Edit & Continue (/ZI)" | ||
===Is there a way to specify build dependencies for Visual Studio 2003 and 2005?=== | ===Is there a way to specify build dependencies for Visual Studio 2003 and 2005?=== | ||
Line 896: | Line 825: | ||
http://lists.trolltech.com/qt-interest/2006-07/thread00238-0.html | http://lists.trolltech.com/qt-interest/2006-07/thread00238-0.html | ||
===Are there seperate versions for CDT 3.1 and CDT 4.0?=== | ===Are there seperate versions for CDT 3.1 and CDT 4.0?=== | ||
No, the provided Qt Eclipse Integration package works with both CDT versions. | No, the provided Qt Eclipse Integration package works with both CDT versions. | ||
===How can I move the origin of a QGraphicsScene to the top left corner of the view?=== | ===How can I move the origin of a QGraphicsScene to the top left corner of the view?=== | ||
By default, the scene rectangle will be aligned to the view's center. So when the view gets larger, the scene will stay in the center of it. You can change the alignment of the scene with the QGraphicsView::setAlignment() http://doc.qt.io/qt-5/qgraphicsview.html#alignment-prop function. | By default, the scene rectangle will be aligned to the view's center. So when the view gets larger, the scene will stay in the center of it. You can change the alignment of the scene with the QGraphicsView::setAlignment() http://doc.qt.io/qt-5/qgraphicsview.html#alignment-prop function. | ||
===How can I make the focus go from one cell to the next when hitting Enter?=== | ===How can I make the focus go from one cell to the next when hitting Enter?=== | ||
In order to make the focus go from one cell to the next in a table when hitting Enter, you can reimplement the delegate's eventFilter() http://doc.qt.io/qt-5 | In order to make the focus go from one cell to the next in a table when hitting Enter, you can reimplement the delegate's eventFilter() http://doc.qt.io/qt-5/qstyleditemdelegate.html#eventFilter and listen for QEvent::KeyPress http://doc.qt.io/qt-5/qevent.html#Type-enum. Then when the key is Enter, you can simply emit commitData(editor) and closeEditor(editor,QAbstractItemDelegate::EditNextItem) and return. | ||
See the documentation on commitData() http://doc.qt.io/qt-5 | See the documentation on commitData() http://doc.qt.io/qt-5/qabstractitemview.html#commitData and closeEditor() http://doc.qt.io/qt-5/qabstractitemview.html#closeEditor | ||
The following example demonstrates how this can be done: | The following example demonstrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class MyItemDelegate : public QStyledItemDelegate | class MyItemDelegate : public QStyledItemDelegate | ||
{ | { | ||
Q_OBJECT | Q_OBJECT | ||
public: | public: | ||
MyItemDelegate(QObject *parent = | MyItemDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) | ||
{ | { | ||
installEventFilter(this); | installEventFilter(this); | ||
} | } | ||
bool eventFilter ( QObject * editor, QEvent * event ) | bool eventFilter (QObject *editor, QEvent *event) | ||
{ | { | ||
if (event->type() == QEvent::KeyPress) | if (event->type() == QEvent::KeyPress) | ||
{ | { | ||
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event); | QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event); | ||
if (keyEvent->key() == Qt::Key_Return) | if (keyEvent->key() == Qt::Key_Return) | ||
{ | { | ||
qDebug() << "Ate key press" << keyEvent->key(); | qDebug() << "Ate key press" << keyEvent->key(); | ||
Line 959: | Line 889: | ||
TableWidget box; | TableWidget box; | ||
box.show(); | box.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How to avoid that space is replaced with %20 when writing .ini files?=== | ===How to avoid that space is replaced with %20 when writing .ini files?=== | ||
Line 969: | Line 899: | ||
http://doc.qt.io/qt-5/qsettings.html#setIniCodec | http://doc.qt.io/qt-5/qsettings.html#setIniCodec | ||
What you should do here is either post-process the file to replace the escaped characters back . The other option is to register your own format with registerFormat() http://doc.qt.io/qt-5/qsettings.html#registerFormat. | What you should do here is either post-process the file to replace the escaped characters back . The other option is to register your own format with registerFormat() http://doc.qt.io/qt-5/qsettings.html#registerFormat. | ||
===Why doesn't my service created with QtService start?=== | ===Why doesn't my service created with QtService start?=== | ||
In order for a service to start it is necessary to copy over the Qt dlls that are being used to the same directory as your application.exe. This is necessary to do because a service is started with only system environment variables set. i.e. QTDIR/bin is usually not part of that environment, so the system is most likely not able to locate the Qt dlls. | In order for a service to start it is necessary to copy over the Qt dlls that are being used to the same directory as your application.exe. This is necessary to do because a service is started with only system environment variables set. i.e. QTDIR/bin is usually not part of that environment, so the system is most likely not able to locate the Qt dlls. | ||
===How to allow only a single column to be editable in a QTreeWidget?=== | ===How to allow only a single column to be editable in a QTreeWidget?=== | ||
The flags for QTreeWidgetItems http://doc.qt.io/qt-5 | The flags for QTreeWidgetItems http://doc.qt.io/qt-5/qtreewidgetitem.html are set for the entire item and all columns. For more flexibility, you may wish to use a QTreeView http://doc.qt.io/qt-5/qtreeview.html and QStandardItemModel http://doc.qt.io/qt-5/qstandarditemmodel.html, which lets you set the flags on individual items. | ||
The documentation for QStandardItemModel contains a small example on how to create a tree model. | The documentation for QStandardItemModel contains a small example on how to create a tree model. | ||
===How do I make a combobox look similar to the one used in file dialogs?=== | ===How do I make a combobox look similar to the one used in file dialogs?=== | ||
The differences with the combobox used in a file dialog is that it shows a hierarchical view and although this is possible by padding items with space you run into problems when you have icons as well as text as the icons are not padded. | The differences with the combobox used in a file dialog is that it shows a hierarchical view and although this is possible by padding items with space you run into problems when you have icons as well as text as the icons are not padded. | ||
To achieve this functionality then you can set a QTreeView http://doc.qt.io/qt-5 | To achieve this functionality then you can set a QTreeView http://doc.qt.io/qt-5/qtreeview.html on the QComboBox http://doc.qt.io/qt-5/qcombobox.html and with a tweak of some of the settings you can get it to resemble the combobox used on a QFileDialog http://doc.qt.io/qt-5/qfiledialog.html. | ||
The following is an example of how this can be done: | The following is an example of how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
Line 1,014: | Line 944: | ||
si->insertRow(0, childSi); | si->insertRow(0, childSi); | ||
sim->setItem(0, 0, si); | sim->setItem(0, 0, si); | ||
cb.setModel(sim); | cb.setModel(sim); | ||
cb.setModelColumn(0); | cb.setModelColumn(0); | ||
Line 1,024: | Line 954: | ||
} | } | ||
</ | </syntaxhighlight> | ||
NB: The call to QTimer::singleShot() is necessary as the expansion of the items needs to occur after the QComboBox and QTreeView are fully initalized after it gets shown. | NB: The call to QTimer::singleShot() is necessary as the expansion of the items needs to occur after the QComboBox and QTreeView are fully initalized after it gets shown. | ||
===Setting thread processor affinity in Linux=== | ===Setting thread processor affinity in Linux=== | ||
If you want to set CPU affinity per QThread http://doc.qt.io/qt-5 | If you want to set CPU affinity per QThread http://doc.qt.io/qt-5/qthread.html, Qt does not provide an API do this, and you will need to use native platform calls. Qt provides a native handle to the currently running thread via the static method QThread::currentThreadId() http://doc.qt.io/qt-5/qthread.html#currentThreadId. | ||
In Linux you will want to take a look at pthread_setaffinity_np() (in /usr/include/pthread.h) which lets you set the affinity of a thread. The id returned by QThread::currentThreadId() is the same as pthread_self(), so to change the affinity of the current thread, you could do something like this: | In Linux you will want to take a look at pthread_setaffinity_np() (in /usr/include/pthread.h) which lets you set the affinity of a thread. The id returned by QThread::currentThreadId() is the same as pthread_self(), so to change the affinity of the current thread, you could do something like this: | ||
<syntaxhighlight lang="cpp"> | |||
cpu_set_t cpuset; | cpu_set_t cpuset; | ||
CPU_ZERO(&cpuset); | CPU_ZERO(&cpuset); | ||
CPU_SET(cpuNumber, &cpuset); | CPU_SET(cpuNumber, &cpuset); | ||
</ | </syntaxhighlight> | ||
... | ... | ||
< | <syntaxhighlight lang="cpp"> | ||
pthread_setaffinity((pthread_t) QThread::currentThreadId(), &cpuset); | pthread_setaffinity((pthread_t) QThread::currentThreadId(), &cpuset); | ||
</ | </syntaxhighlight> | ||
You could just use pthread_self() as well, avoiding the cast. | You could just use pthread_self() as well, avoiding the cast. | ||
===Use of setCellWidget (in QTableWidget) and signal connections=== | ===Use of setCellWidget (in QTableWidget) and signal connections=== | ||
The widgets set on the cells have nothing to do with the contents of the table, so you won't get signals from the table in such a case. If you have a row or column of widgets potentially emitting signals, and you want one slot to be notified of the row/column index of the widget that was triggered, then QSignalMapper http://doc.qt.io/qt-5/qsignalmapper.html#map could be the way to go. | The widgets set on the cells have nothing to do with the contents of the table, so you won't get signals from the table in such a case. If you have a row or column of widgets potentially emitting signals, and you want one slot to be notified of the row/column index of the widget that was triggered, then QSignalMapper http://doc.qt.io/qt-5/qsignalmapper.html#map could be the way to go. | ||
The following example illustrates how this can be done: | The following example illustrates how this can be done: | ||
Line 1,053: | Line 983: | ||
main.cpp | main.cpp | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class CustomWidget : public QWidget{ | class CustomWidget : public QWidget{ | ||
Line 1,060: | Line 990: | ||
public: | public: | ||
CustomWidget(QWidget *parent = | CustomWidget(QWidget *parent = parent) : QWidget(parent) | ||
{ | |||
table = new QTableWidget(7,4,this); | table = new QTableWidget(7,4,this); | ||
signalMapper = new QSignalMapper(this); | signalMapper = new QSignalMapper(this); | ||
Line 1,104: | Line 1,035: | ||
} | } | ||
</ | </syntaxhighlight> | ||
===When doing Qt | Open Solution from .pro file in Visual Studio 2005 I get an error saying the sln file is from a previous version of Visual Studio and must be converted, what can I do?=== | ===When doing Qt | Open Solution from .pro file in Visual Studio 2005 I get an error saying the sln file is from a previous version of Visual Studio and must be converted, what can I do?=== | ||
Line 1,113: | Line 1,044: | ||
# Open the sln file in Visual Studio 2005 and you will get a conversion dialog. Answer yes in this dialog and the sln file will be converted to the 2005 format instead of 2003. | # Open the sln file in Visual Studio 2005 and you will get a conversion dialog. Answer yes in this dialog and the sln file will be converted to the 2005 format instead of 2003. | ||
# Use the command prompt that can be found under *Start menu | Visual Studio 2005 | Command prompt*. Type *devenv /usenv* in this command prompt and this will ensure that the correct environment variables are set and that you should be able to use the Open Solution from .pro file option inside Visual Studio. | # Use the command prompt that can be found under *Start menu | Visual Studio 2005 | Command prompt*. Type *devenv /usenv* in this command prompt and this will ensure that the correct environment variables are set and that you should be able to use the Open Solution from .pro file option inside Visual Studio. | ||
===When building with Visual C++, it uses a different copy of a specified file that has the same name. How do I fix this?=== | ===When building with Visual C++, it uses a different copy of a specified file that has the same name. How do I fix this?=== | ||
Line 1,119: | Line 1,050: | ||
building in batch mode, it will find the first copy of the file in the paths | building in batch mode, it will find the first copy of the file in the paths | ||
and assume that is the right one. You can work around this problem by doing: | and assume that is the right one. You can work around this problem by doing: | ||
< | <syntaxhighlight> | ||
CONFIG += no_batch | CONFIG += no_batch | ||
</ | </syntaxhighlight> | ||
in your pro file. | in your pro file. | ||
===I am having problems displaying overlays on Linux with my NVIDIA card. The same code works on windows.=== | ===I am having problems displaying overlays on Linux with my NVIDIA card. The same code works on windows.=== | ||
The NVIDIA driver only offers RGBA overlays. The default setting in QGLFormat is to use an index-based overlays. You can switch to RGBA overlays using this code: | The NVIDIA driver only offers RGBA overlays. The default setting in QGLFormat is to use an index-based overlays. You can switch to RGBA overlays using this code: | ||
< | <syntaxhighlight lang="cpp"> | ||
QGLFormat f = QGLFormat::defaultOverlayFormat(); | QGLFormat f = QGLFormat::defaultOverlayFormat(); | ||
f.setRgba(true); | f.setRgba(true); | ||
QGLFormat::setDefaultOverlayFormat(f); | QGLFormat::setDefaultOverlayFormat(f); | ||
</ | </syntaxhighlight> | ||
===How to add to the beginning of a QDomDocument?="<?xml version === | ===How to add to the beginning of a QDomDocument?="<?xml version === | ||
Line 1,139: | Line 1,070: | ||
first child of the document: | first child of the document: | ||
< | <syntaxhighlight lang="cpp"> | ||
QDomDocument doc; | QDomDocument doc; | ||
doc.appendChild(doc.createProcessingInstruction(xml version =,'1.0')); | doc.appendChild(doc.createProcessingInstruction(xml version =,'1.0')); | ||
doc.appendChild(doc.createElement("hi"));</ | doc.appendChild(doc.createElement("hi"));</syntaxhighlight> | ||
===How can I do drag and drop in a widget?=== | ===How can I do drag and drop in a widget?=== | ||
Drag and drop support in Qt is centered around the QDrag http://doc.qt.io/qt-5/qdrag.html class that handles most of the details of a drag and drop operation. | Drag and drop support in Qt is centered around the QDrag http://doc.qt.io/qt-5/qdrag.html class that handles most of the details of a drag and drop operation. | ||
In addition to creating a QDrag object, you need to reimplement dragMoveEvent() http://doc.qt.io/qt-5/qwidget.html#dragMoveEvent to accept the event and dropEvent() http://doc.qt.io/qt-5/qwidget.html#dropEvent to handle the data dropped on the widget. Finally dragEnterEvent() http://doc.qt.io/qt-5 | In addition to creating a QDrag object, you need to reimplement dragMoveEvent() http://doc.qt.io/qt-5/qwidget.html#dragMoveEvent to accept the event and dropEvent() http://doc.qt.io/qt-5/qwidget.html#dropEvent to handle the data dropped on the widget. Finally dragEnterEvent() http://doc.qt.io/qt-5/qwidget.html#dragEnterEvent needs to be reimplemented to accept the event. | ||
You also need to call | You also need to call | ||
< | <syntaxhighlight lang="cpp">setAcceptDrops(true) </syntaxhighlight> | ||
on the widgets that should be able to accept a drop. | on the widgets that should be able to accept a drop. | ||
Line 1,161: | Line 1,092: | ||
The example below illustrates how this can be done. | The example below illustrates how this can be done. | ||
< | <syntaxhighlight lang="cpp">#include <QtWidgets> | ||
class MyDialog : public QWidget | class MyDialog : public QWidget | ||
Line 1,167: | Line 1,098: | ||
Q_OBJECT | Q_OBJECT | ||
public: | public: | ||
MyDialog(QWidget *parent = | MyDialog(QWidget *parent = nullptr); | ||
public slots: | public slots: | ||
void makeDrag(); | void makeDrag(); | ||
Line 1,179: | Line 1,110: | ||
{ | { | ||
public: | public: | ||
MyGroupBox(QWidget *parent = | MyGroupBox(QWidget *parent = parent) : QGroupBox(parent) {}; | ||
protected: | protected: | ||
void dropEvent(QDropEvent *de); | void dropEvent(QDropEvent *de); | ||
Line 1,256: | Line 1,187: | ||
d.show(); | d.show(); | ||
return a.exec(); | return a.exec(); | ||
}</ | }</syntaxhighlight> | ||
===How can I tell qmake to have more than one target in a directory?=== | ===How can I tell qmake to have more than one target in a directory?=== | ||
Line 1,266: | Line 1,197: | ||
This will allow you to have several executables in the same directory. | This will allow you to have several executables in the same directory. | ||
===How can I get hold of all of the visible items in my QTreeWidget?=== | ===How can I get hold of all of the visible items in my QTreeWidget?=== | ||
In order to get a list of the visible items in a QTreeWidget http://doc.qt.io/qt-5 | In order to get a list of the visible items in a QTreeWidget http://doc.qt.io/qt-5/qtreewidget.html, then you can use itemAt(0,0) to get the first item, then use itemBelow() http://doc.qt.io/qt-5/qtreewidget.html#itemBelow to get the next and then do, | ||
< | <syntaxhighlight lang="cpp">if (viewport()->rect().contains(visualItemRect(itemBelow(myItem))</syntaxhighlight> | ||
to determine if it's actually on the viewport or not. See the documentation: | to determine if it's actually on the viewport or not. See the documentation: | ||
Line 1,280: | Line 1,211: | ||
The following example demonstrates how this can be done: | The following example demonstrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
QList <QTreeWidgetItem*>myList; | QList <QTreeWidgetItem*>myList; | ||
Line 1,288: | Line 1,219: | ||
Q_OBJECT | Q_OBJECT | ||
public: | public: | ||
TreeWidget() | TreeWidget(QWidget *parent = nullptr) : QTreeWidget(parent) | ||
{ | { | ||
QStringList list; | QStringList list; | ||
Line 1,307: | Line 1,238: | ||
addTopLevelItem(item4); | addTopLevelItem(item4); | ||
item1->setExpanded(true); | item1->setExpanded(true); | ||
} | } | ||
public slots: | public slots: | ||
Line 1,341: | Line 1,272: | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Why is the debug version of my application so slow?=== | ===Why is the debug version of my application so slow?=== | ||
Line 1,355: | Line 1,286: | ||
Then all that is left is to regenerate the Makefile for your application and rebuild it. | Then all that is left is to regenerate the Makefile for your application and rebuild it. | ||
===Why isn't the parent's font propagated to QAbstractItemView subclasses on Windows?=== | ===Why isn't the parent's font propagated to QAbstractItemView subclasses on Windows?=== | ||
The reason the parent's font is not propagated to subclasses of QAbstractItemView http://doc.qt.io/qt-5 | The reason the parent's font is not propagated to subclasses of QAbstractItemView http://doc.qt.io/qt-5/qabstractitemview.html is that it has its own font set in qapplication_win.cpp. This is to ensure that the itemviews have a font that matches what you would get in a native itemview on Windows. | ||
To have the font propagated you need to set the font for the relevant class to an empty font in your QApplication http://doc.qt.io/qt-5 | To have the font propagated you need to set the font for the relevant class to an empty font in your QApplication http://doc.qt.io/qt-5/qapplication.html, e.g.: | ||
< | <syntaxhighlight lang="cpp"> | ||
QApplication::setFont(QFont(), "QAbstractItemView"); | QApplication::setFont(QFont(), "QAbstractItemView"); | ||
</ | </syntaxhighlight> | ||
Another option is to set a stylesheet http://doc.qt.io/qt-5 | Another option is to set a stylesheet http://doc.qt.io/qt-5/stylesheet.html: | ||
< | <syntaxhighlight lang="cpp"> | ||
app.setStyleSheet("*{font ...}"); | app.setStyleSheet("*{font ...}"); | ||
</ | </syntaxhighlight> | ||
Line 1,382: | Line 1,313: | ||
On Mac OS X, double buffering and widget composition is done entirely by the windowing system, and setting this flag has no effect. | On Mac OS X, double buffering and widget composition is done entirely by the windowing system, and setting this flag has no effect. | ||
===Does Qt Assistant support the MNG format?=== | ===Does Qt Assistant support the MNG format?=== | ||
Qt Assistant http://doc.qt.io/qt-5 | Qt Assistant http://doc.qt.io/qt-5/assistant-manual.html does not support the MNG format (the animated PNG format). | ||
===I am getting linking errors when trying to link against msvcrtd.lib. And when linking against libcmt.lib the application crashes. What can I do ?=== | ===I am getting linking errors when trying to link against msvcrtd.lib. And when linking against libcmt.lib the application crashes. What can I do ?=== | ||
Line 1,413: | Line 1,344: | ||
just references those two symbols: | just references those two symbols: | ||
< | <syntaxhighlight lang="cpp"> | ||
extern C { | extern C { | ||
int __mb_cur_max; | int __mb_cur_max; | ||
unsigned short* _pctype; | unsigned short* _pctype; | ||
int errno; | int errno; | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Why do I get hundreds of warnings when the compiler warning level is set to level 4 for | |||
===Why do I get hundreds of warnings when the compiler warning level is set to level 4 for MSVC?=== | |||
We do not support building with warning level 4. The warnings generated at | We do not support building with warning level 4. The warnings generated at | ||
this level are often not valid, this is why we build at warning level 3. | this level are often not valid, this is why we build at warning level 3. | ||
===When 2 views share the same model, how can the views get different values for some of the Qt::ItemDataRole roles?=== | ===When 2 views share the same model, how can the views get different values for some of the Qt::ItemDataRole roles?=== | ||
The model does not have any information about the views, so your item delegate will have to handle this. If you want one of your views to have icons and not the other one, then you can reimplement QItemDelegate::drawDecoration() http://doc.qt.io/qt-5/qitemdelegate.html#drawDecoration and set the delegate on that view, e.g: | The model does not have any information about the views, so your item delegate will have to handle this. If you want one of your views to have icons and not the other one, then you can reimplement QItemDelegate::drawDecoration() http://doc.qt.io/qt-5/qitemdelegate.html#drawDecoration and set the delegate on that view, e.g: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class ItemDelegate : public QItemDelegate | class ItemDelegate : public QItemDelegate | ||
{ | { | ||
public: | public: | ||
using QItemDelegate::QItemDelegate; | |||
void drawDecoration(QPainter *painter, const QStyleOptionViewItem &option, | void drawDecoration(QPainter *painter, const QStyleOptionViewItem &option, | ||
const QRect &rect, const QPixmap &pixmap) const | const QRect &rect, const QPixmap &pixmap) const override | ||
{ | { | ||
QPixmap pix(22, 22); | QPixmap pix(22, 22); | ||
Line 1,481: | Line 1,403: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
Alternatively, you can reimplement | Alternatively, you can reimplement QSytledItemDelegate::paint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#paint and draw the pixmap and the other details there. | ||
===How can I make both the item picture and the item text transparent in the drag icon so that user can see what is under the drag icon?=== | ===How can I make both the item picture and the item text transparent in the drag icon so that user can see what is under the drag icon?=== | ||
Whether or not transparent drag icons are supported is platform dependent. For instance Windows 2000 does not support this. So the simplest way to achieve this is to display what you want to drag in a toplevel QLabel http://doc.qt.io/qt-5 | Whether or not transparent drag icons are supported is platform dependent. For instance Windows 2000 does not support this. So the simplest way to achieve this is to display what you want to drag in a toplevel QLabel http://doc.qt.io/qt-5/qlabel.htmland give this label a window opacity http://doc.qt.io/qt-5/qwidget.html#windowOpacity-prop | ||
===I can still insert numbers outside the range specified with a QDoubleValidator on a QLineEdit, is this a bug?=== | ===I can still insert numbers outside the range specified with a QDoubleValidator on a QLineEdit, is this a bug?=== | ||
Line 1,496: | Line 1,418: | ||
The example below reimplements validate() http://doc.qt.io/qt-5/qvalidator.html#validate to make the validator more strict: | The example below reimplements validate() http://doc.qt.io/qt-5/qvalidator.html#validate to make the validator more strict: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include <qapplication.h> | #include <qapplication.h> | ||
#include <qmainwindow.h> | #include <qmainwindow.h> | ||
Line 1,505: | Line 1,427: | ||
{ | { | ||
public: | public: | ||
MyDoubleValidator( double bottom, double top, int decimals, QObject* | MyDoubleValidator(double bottom, double top, int decimals, QObject *parent = nullptr) | ||
: QDoubleValidator(bottom, top, decimals, parent) | |||
: QDoubleValidator( bottom, top, decimals, parent | |||
{} | {} | ||
QValidator::State validate ( QString & input, int &pos ) const | QValidator::State validate(QString &input, int &pos) const override | ||
{ | { | ||
if ( input.isEmpty() || input == . ) | if (input.isEmpty() || input == "."") | ||
return Intermediate; | return Intermediate; | ||
if ( QDoubleValidator::validate( input, pos ) != Acceptable ) { | if (QDoubleValidator::validate(input, pos) != Acceptable) { | ||
return Invalid; | return Invalid; | ||
} | } | ||
Line 1,525: | Line 1,446: | ||
Q_OBJECT | Q_OBJECT | ||
public: | public: | ||
Widget( QWidget* parent = | Widget(QWidget *parent = nullptr) | ||
: QMainWindow( parent | : QMainWindow(parent) | ||
{ | { | ||
QLineEdit* edit = new QLineEdit( this ); | QLineEdit *edit = new QLineEdit( this ); | ||
setCentralWidget( edit ); | setCentralWidget( edit ); | ||
edit->setValidator( new MyDoubleValidator( 0.0, 1.0, 3, edit ) ); | edit->setValidator( new MyDoubleValidator( 0.0, 1.0, 3, edit ) ); | ||
Line 1,543: | Line 1,464: | ||
return a.exec(); | return a.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I draw one of my menu items, e.g Help, to the right in the menubar ?=== | ===How can I draw one of my menu items, e.g Help, to the right in the menubar ?=== | ||
You can call insertSeparator() http://doc.qt.io/qt-5/qmenu.html#insertSeparator in order to insert a separator before the Help action. Whether or not this separator is drawn, is style dependent however. It will not be drawn in the Windows(XP) Style. So you can either call | You can call insertSeparator() http://doc.qt.io/qt-5/qmenu.html#insertSeparator in order to insert a separator before the Help action. Whether or not this separator is drawn, is style dependent however. It will not be drawn in the Windows(XP) Style. So you can either call | ||
< | <syntaxhighlight lang="cpp">menuBar()->setStyle(new QMotifStyle()) </syntaxhighlight> | ||
or subclass the style and reimplement the stylehint() http://doc.qt.io/qt-5/qstyle.html#styleHint to return the SH_DrawMenuBarSeparator http://doc.qt.io/qt-5 | or subclass the style and reimplement the stylehint() http://doc.qt.io/qt-5/qstyle.html#styleHint to return the SH_DrawMenuBarSeparator http://doc.qt.io/qt-5/qstyle.html#StyleHint-enum hint. | ||
The following example demonstrates how this can be done: | The following example demonstrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Style : public QWindowsStyle | class Style : public QWindowsStyle | ||
{ | { | ||
public: | public: | ||
Style() | Style() {} | ||
int styleHint(StyleHint hint, const QStyleOption *option = | int styleHint(StyleHint hint, const QStyleOption *option = nullptr, const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const | ||
{ | |||
if (hint == QStyle::SH_DrawMenuBarSeparator) | if (hint == QStyle::SH_DrawMenuBarSeparator) | ||
return 1; | return 1; | ||
Line 1,596: | Line 1,516: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I turn off the debug and release Makefile generation for my application?=== | ===How can I turn off the debug and release Makefile generation for my application?=== | ||
Simply add the following line to your pro file: | Simply add the following line to your pro file: | ||
< | <syntaxhighlight> CONFIG -= debug_and_release</syntaxhighlight> | ||
===When setting a pixmap with an alpha on a widget, how can I remove the widget's gray edges that shine through?=== | ===When setting a pixmap with an alpha on a widget, how can I remove the widget's gray edges that shine through?=== | ||
In order to remove the non-transparent edges from the widget, you can set a heuristic mask on the pixmap. This will cause the outer most color to be removed where it is used in the pixmap. Then you can set the QBitmap http://doc.qt.io/qt-5 | In order to remove the non-transparent edges from the widget, you can set a heuristic mask on the pixmap. This will cause the outer most color to be removed where it is used in the pixmap. Then you can set the QBitmap http://doc.qt.io/qt-5/qbitmap.html which is returned from the call to createHeuristicMask() http://doc.qt.io/qt-5/qpixmap.html#createHeuristicMask as a mask on your widget. This will cause only the pixels of the widget for which bitmap has a corresponding 1 bit to be visible. Now you can set your pixmap on the widget, and only the pixels that correspond to where the mask has a bit set will be visible. | ||
See the following example for a demonstration: | See the following example for a demonstration: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
Line 1,624: | Line 1,544: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Is it possible to have no icons in the menu when using actions but use the same actions on a toolbar and have an icon there?=== | ===Is it possible to have no icons in the menu when using actions but use the same actions on a toolbar and have an icon there?=== | ||
On the Mac you can call | On the Mac you can call | ||
< | <syntaxhighlight lang="cpp">qt_mac_set_Menubar_icons(false)</syntaxhighlight> | ||
this will prevent the icons from showing up in the menu. See the documentation http://doc.qt.io/qt-5/exportedfunctions.html#void-qt-mac-set-menubar-icons-bool-enable. | this will prevent the icons from showing up in the menu. See the documentation http://doc.qt.io/qt-5/exportedfunctions.html#void-qt-mac-set-menubar-icons-bool-enable. | ||
Alternatively, you can iterate over the toolbar's toolbutton children and set an icon http://doc.qt.io/qt-5/qabstractbutton.html#icon-prop on them. | Alternatively, you can iterate over the toolbar's toolbutton children and set an icon http://doc.qt.io/qt-5/qabstractbutton.html#icon-prop on them. | ||
See the following example for a demonstration: | See the following example for a demonstration: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
QPixmap pix(15,15); | QPixmap pix(15,15); | ||
pix.fill(Qt::red); | pix.fill(Qt::red); | ||
QMainWindow box; | QMainWindow box; | ||
QAction *action = new QAction("First action", &box); | QAction *action = new QAction("First action", &box); | ||
QAction *action2 = new QAction("Second action", &box); | QAction *action2 = new QAction("Second action", &box); | ||
QToolBar *toolBar = new QToolBar(&box); | QToolBar *toolBar = new QToolBar(&box); | ||
toolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); | toolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); | ||
toolBar->addAction(action); | toolBar->addAction(action); | ||
toolBar->addAction(action2); | toolBar->addAction(action2); | ||
QList<QToolButton*> toolButtons = qFindChildren<QToolButton*>(toolBar); | QList<QToolButton*> toolButtons = qFindChildren<QToolButton*>(toolBar); | ||
for (int i = 0; i < toolButtons.size(); i++) { | for (int i = 0; i < toolButtons.size(); i++) { | ||
QToolButton *button = (QToolButton*)toolButtons.at(i); | QToolButton *button = (QToolButton*)toolButtons.at(i); | ||
button->setIcon(pix); | button->setIcon(pix); | ||
} | } | ||
QMenu *menu = new QMenu("File", &box); | QMenu *menu = new QMenu("File", &box); | ||
menu->addAction(action); | menu->addAction(action); | ||
menu->addAction(action2); | menu->addAction(action2); | ||
box.menuBar()->addMenu(menu); | box.menuBar()->addMenu(menu); | ||
box.addToolBar(toolBar); | box.addToolBar(toolBar); | ||
box.show(); | box.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Can you suggest a tool which we can use to track down memory leaks in Qt?=== | ===Can you suggest a tool which we can use to track down memory leaks in Qt?=== | ||
Line 1,673: | Line 1,593: | ||
Internally, we use Purify on Windows and on Linux we use Valgrind. | Internally, we use Purify on Windows and on Linux we use Valgrind. | ||
===How can I check which tab is the current one in a tabbed QDockWidget?=== | ===How can I check which tab is the current one in a tabbed QDockWidget?=== | ||
You need to find the QTabBar http://doc.qt.io/qt-5/qtabbar.html that exists for the tabbed dockwidgets and then simply call tabBar->currentIndex() http://doc.qt.io/qt-5/qtabbar.html#currentIndex-prop on it to find the current index and connect a slot to the tabbar's currentChanged() http://doc.qt.io/qt-5/qtabbar.html#currentChanged slot. The example below shows how you can do this. | You need to find the QTabBar http://doc.qt.io/qt-5/qtabbar.html that exists for the tabbed dockwidgets and then simply call tabBar->currentIndex() http://doc.qt.io/qt-5/qtabbar.html#currentIndex-prop on it to find the current index and connect a slot to the tabbar's currentChanged() http://doc.qt.io/qt-5/qtabbar.html#currentChanged slot. The example below shows how you can do this. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class MainWindow : public QMainWindow | class MainWindow : public QMainWindow | ||
{ | { | ||
Q_OBJECT | Q_OBJECT | ||
public: | public: | ||
MainWindow(QWidget *parent = | MainWindow(QWidget *parent = nullptr) | ||
: QMainWindow(parent) | : QMainWindow(parent) | ||
{ | { | ||
Line 1,721: | Line 1,641: | ||
void testSlot(int index) | void testSlot(int index) | ||
{ | { | ||
qDebug() << "current tab is " << index; | qDebug() << "current tab is " << index; | ||
} | } | ||
}; | }; | ||
Line 1,734: | Line 1,654: | ||
return a.exec(); | return a.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can we remove properties from custom widgets in Designer?=== | ===How can we remove properties from custom widgets in Designer?=== | ||
You can remove properties from custom widgets in Designer using the QtDesignerPropertySheetExtension http://doc.qt.io/qt-5/qdesignerpropertysheetextension.html. This class allows you to manipulate a widget's properties which are displayed in Qt Designer's property editor. | You can remove properties from custom widgets in Designer using the QtDesignerPropertySheetExtension http://doc.qt.io/qt-5/qdesignerpropertysheetextension.html. This class allows you to manipulate a widget's properties which are displayed in Qt Designer's property editor. | ||
You can setVisible(false) to hide the properties you want in Designer. See the documentation on setVisible() http://doc.qt.io/qt-5/qdesignerpropertysheetextension.html#setVisible. | You can setVisible(false) to hide the properties you want in Designer. See the documentation on setVisible() http://doc.qt.io/qt-5/qdesignerpropertysheetextension.html#setVisible. | ||
===How can I open my .html file in a browser?=== | ===How can I open my .html file in a browser?=== | ||
Line 1,750: | Line 1,670: | ||
for the system. So if you call | for the system. So if you call | ||
< | <syntaxhighlight lang="cpp"> | ||
QDesktopServices::openUrl("http://qt.io/"); | QDesktopServices::openUrl("http://qt.io/"); | ||
</ | </syntaxhighlight> | ||
then a web browser as set by the system will be invoked to display the page. The actual web browser used depends on the system settings, so this could be Firefox, Internet Explorer, Opera or Safari etc. | then a web browser as set by the system will be invoked to display the page. The actual web browser used depends on the system settings, so this could be Firefox, Internet Explorer, Opera or Safari etc. | ||
Line 1,759: | Line 1,679: | ||
===How can I build executables/libraries in both release and debug mode on Windows?=== | ===How can I build executables/libraries in both release and debug mode on Windows?=== | ||
Qt is built in both debug and release mode by default on Windows. When it comes to building your applications/libraries, you can specify | Qt is built in both debug and release mode by default on Windows. When it comes to building your applications/libraries, you can specify | ||
< | <syntaxhighlight>CONFIG += debug_and_release</syntaxhighlight> | ||
in your .pro file (this is already on by default on Windows). | in your .pro file (this is already on by default on Windows). | ||
Line 1,770: | Line 1,690: | ||
If you want only one configuration to be generated, then whatever is last on the CONFIG line with respect to debug and release will be the one that qmake generates. If you want it to build both configurations of your application/library, then you need to add: | If you want only one configuration to be generated, then whatever is last on the CONFIG line with respect to debug and release will be the one that qmake generates. If you want it to build both configurations of your application/library, then you need to add: | ||
< | <syntaxhighlight>CONFIG += build_all</syntaxhighlight> | ||
to your pro file and then whenever you do nmake, both the debug and release versions will be built. | to your pro file and then whenever you do nmake, both the debug and release versions will be built. | ||
===Who provides training for Qt?=== | ===Who provides training for Qt?=== | ||
Line 1,779: | Line 1,699: | ||
===Qt seems to ignore the key sequence Ctrl++, is this a valid key sequence that Qt should recognize?=== | ===Qt seems to ignore the key sequence Ctrl++, is this a valid key sequence that Qt should recognize?=== | ||
Line 1,801: | Line 1,721: | ||
See the following example for a demonstration: | See the following example for a demonstration: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class MainWindow : public QMainWindow | class MainWindow : public QMainWindow | ||
{ | { | ||
Q_OBJECT | Q_OBJECT | ||
public: | public: | ||
MainWindow::MainWindow() : QMainWindow() | MainWindow::MainWindow() : QMainWindow() | ||
{ | { | ||
QAction* action = new QAction("Test", this); | QAction* action = new QAction("Test", this); | ||
QMenu *menu = menuBar()->addMenu("File"); | QMenu *menu = menuBar()->addMenu("File"); | ||
menu->addAction(action); | menu->addAction(action); | ||
connect( action, SIGNAL(triggered()), this, SLOT (giveOutput())); | connect( action, SIGNAL(triggered()), this, SLOT (giveOutput())); | ||
action->setShortcut(Qt::SHIFT+Qt::CTRL+Qt::Key_Equal); | action->setShortcut(Qt::SHIFT+Qt::CTRL+Qt::Key_Equal); | ||
action->setShortcut(Qt::CTRL+Qt::Key_Plus); | action->setShortcut(Qt::CTRL+Qt::Key_Plus); | ||
} | } | ||
public slots: | public slots: | ||
void giveOutput() { | void giveOutput() { | ||
qDebug("I was called"); } | qDebug("I was called"); } | ||
}; | }; | ||
#include "main.moc" | #include "main.moc" | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
MainWindow box; | MainWindow box; | ||
box.show(); | box.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I draw a question mark on an existing pixmap?=== | ===How can I draw a question mark on an existing pixmap?=== | ||
You open a painter on the pixmap and depending on how your question mark is | You open a painter on the pixmap and depending on how your question mark is | ||
represented, draw either the text string ?, or a polygon or a painter path describing the shape of a question mark. | represented, draw either the text string ?, or a polygon or a painter path describing the shape of a question mark. | ||
===How can I run a Qt application on a Unix machine that doesn't have X11 installed?=== | ===How can I run a Qt application on a Unix machine that doesn't have X11 installed?=== | ||
Qt is divided into several libraries. QtCore http://doc.qt.io/qt-5 | Qt is divided into several libraries. QtCore http://doc.qt.io/qt-5/qtcore.html, QtSql http://doc.qt.io/qt-5/qtsql.html, QtNetwork http://doc.qt.io/qt-5/qtnetwork.html and QtXml http://doc.qt.io/qt-5/qtxml.html don't link against X11 so you can use classes contained in this library and run your application on a machine that doesn't have X11 installed. | ||
===Is there a way to set the size of the icon for the items in my item view?=== | ===Is there a way to set the size of the icon for the items in my item view?=== | ||
You can call setIconSize() http://doc.qt.io/qt-5/qabstractitemview.html#iconSize-prop on the view, this will readjust the icon sizes for the items to whatever you set it to. | You can call setIconSize() http://doc.qt.io/qt-5/qabstractitemview.html#iconSize-prop on the view, this will readjust the icon sizes for the items to whatever you set it to. | ||
Note that QIcon only scales down and not up, therefore the original pixmap should be as large as the max size you want to scale up to. | Note that QIcon only scales down and not up, therefore the original pixmap should be as large as the max size you want to scale up to. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
QTableWidget box; | QTableWidget box; | ||
box.horizontalHeader()->setStretchLastSection(true); | box.horizontalHeader()->setStretchLastSection(true); | ||
QPixmap pix(50,50); | QPixmap pix(50,50); | ||
pix.fill(Qt::red); | pix.fill(Qt::red); | ||
QIcon icon(pix); | QIcon icon(pix); | ||
box.setIconSize(QSize(25,25)); | box.setIconSize(QSize(25,25)); | ||
QTableWidgetItem *itemOne = new QTableWidgetItem("one"); | QTableWidgetItem *itemOne = new QTableWidgetItem("one"); | ||
QTableWidgetItem *itemTwo = new QTableWidgetItem("two"); | QTableWidgetItem *itemTwo = new QTableWidgetItem("two"); | ||
QTableWidgetItem *itemThree = new QTableWidgetItem("three"); | QTableWidgetItem *itemThree = new QTableWidgetItem("three"); | ||
itemOne->setIcon(icon); | itemOne->setIcon(icon); | ||
box.setRowCount(5); | box.setRowCount(5); | ||
box.setColumnCount(5); | box.setColumnCount(5); | ||
box.setItem(0,0,itemOne); | box.setItem(0,0,itemOne); | ||
box.setItem(1,0,itemTwo); | box.setItem(1,0,itemTwo); | ||
box.setItem(2,0,itemThree); | box.setItem(2,0,itemThree); | ||
box.show(); | box.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===When a signal is emitted, will all of the slots attached to it be executed before the emit returns? Or are the slots just scheduled to be executed whenever convenient?=== | ===When a signal is emitted, will all of the slots attached to it be executed before the emit returns? Or are the slots just scheduled to be executed whenever convenient?=== | ||
Line 1,880: | Line 1,800: | ||
The order of execution of the slots is undefined. | The order of execution of the slots is undefined. | ||
===I have a complex control where I never want to draw a certain subcontrol, how can I achieve this in Qt 4?=== | ===I have a complex control where I never want to draw a certain subcontrol, how can I achieve this in Qt 4?=== | ||
In order to remove a subcontrol you need to subclass the style and reimplement drawComplexControl() http://doc.qt.io/qt-5 | In order to remove a subcontrol you need to subclass the style and reimplement drawComplexControl() http://doc.qt.io/qt-5/qstyle.html#drawComplexControl and make a copy of the style option and remove that subcontrol from the styleoption. | ||
Here is an example where the frame is removed from a QGroupBox http://doc.qt.io/qt-5 | Here is an example where the frame is removed from a QGroupBox http://doc.qt.io/qt-5/qgroupbox.html | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Style : public QWindowsStyle | class Style : public QWindowsStyle | ||
Line 1,895: | Line 1,815: | ||
public: | public: | ||
Style() {} | Style() {} | ||
void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = | void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = nullptr) const override { | ||
if (const QStyleOptionGroupBox *group = qstyleoption_cast<const QStyleOptionGroupBox*>(option)) { | if (const QStyleOptionGroupBox *group = qstyleoption_cast<const QStyleOptionGroupBox*>(option)) { | ||
QStyleOptionGroupBox newGroupBox(*group); | QStyleOptionGroupBox newGroupBox(*group); | ||
Line 1,919: | Line 1,839: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===What does it mean if the build fails with fatal error U1054=== | ===What does it mean if the build fails with fatal error U1054=== | ||
Line 1,932: | Line 1,852: | ||
restart your Qt installation to work around the problem. You might have to | restart your Qt installation to work around the problem. You might have to | ||
close all your other application to be able to do so. | close all your other application to be able to do so. | ||
===How can I transfer shortcuts that are not available in the child window to the parent window?=== | ===How can I transfer shortcuts that are not available in the child window to the parent window?=== | ||
You can create actions and set a shortcut to them and then add the actions to both the parent and the child as illustrated in the example below: | You can create actions and set a shortcut to them and then add the actions to both the parent and the child as illustrated in the example below: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Parent : public QWidget | class Parent : public QWidget | ||
Line 1,968: | Line 1,888: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I stack the dockwidgets vertically in the top dock area?=== | ===How can I stack the dockwidgets vertically in the top dock area?=== | ||
Line 1,976: | Line 1,896: | ||
In the example below we subclass the private class QDockWidgetLayout and go over the main window's layout's children and cast them to our subclass and make sure to set the orientation to be vertical. Finally, we invalidate the layout to make sure it gets updated. | In the example below we subclass the private class QDockWidgetLayout and go over the main window's layout's children and cast them to our subclass and make sure to set the orientation to be vertical. Finally, we invalidate the layout to make sure it gets updated. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class MyDL :public QDockWidgetLayout | class MyDL :public QDockWidgetLayout | ||
{ | { | ||
public: MyDL(Qt::DockWidgetArea a, Qt::Orientation o) : QDockWidgetLayout(a, o) | public: MyDL(Qt::DockWidgetArea a, Qt::Orientation o) : QDockWidgetLayout(a, o) | ||
{} | {} | ||
}; | }; | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
QMainWindow window; | QMainWindow window; | ||
QDockWidget *dock1 = new QDockWidget(&window); | QDockWidget *dock1 = new QDockWidget(&window); | ||
QDockWidget *dock2 = new QDockWidget(&window); | QDockWidget *dock2 = new QDockWidget(&window); | ||
QDockWidget *dock3 = new QDockWidget(&window); | QDockWidget *dock3 = new QDockWidget(&window); | ||
window.addDockWidget(Qt::TopDockWidgetArea, dock2); | window.addDockWidget(Qt::TopDockWidgetArea, dock2); | ||
window.addDockWidget(Qt::TopDockWidgetArea, dock3); | window.addDockWidget(Qt::TopDockWidgetArea, dock3); | ||
window.addDockWidget(Qt::TopDockWidgetArea, dock1); | window.addDockWidget(Qt::TopDockWidgetArea, dock1); | ||
window.show(); | window.show(); | ||
QList<QLayout*> customLayout = qFindChildren<QLayout*>(window.layout()); | QList<QLayout*> customLayout = qFindChildren<QLayout*>(window.layout()); | ||
for (int i = 0; i < customLayout.size(); i++) | for (int i = 0; i < customLayout.size(); i++) | ||
{ | { | ||
MyDL *dl = (MyDL *)customLayout.at(i); | MyDL *dl = (MyDL *)customLayout.at(i); | ||
dl->QDockWidgetLayout::orientation = Qt::Vertical; | dl->QDockWidgetLayout::orientation = Qt::Vertical; | ||
dl->invalidate(); | dl->invalidate(); | ||
} | } | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I create transparent labels and buttons where the window's background pixmap shines through the label?=== | ===How can I create transparent labels and buttons where the window's background pixmap shines through the label?=== | ||
The label will be transparent by default, so the background pixmap of the parent will shine through the label. For the buttons you need to fill the QPalette::Button http://doc.qt.io/qt-5 | The label will be transparent by default, so the background pixmap of the parent will shine through the label. For the buttons you need to fill the QPalette::Button http://doc.qt.io/qt-5/qpalette.html#ColorRole-enum color role to have no brush. Note that changing the palette will not work for all styles, it will for example not work for the XP and MacStyle which are pixmap based. For these styles you will have to draw this yourself in the paintEvent() http://doc.qt.io/qt-5/qlabel.html#paintEvent or set a style that supports this on the button. | ||
See the following example: | See the following example: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
Line 2,048: | Line 1,968: | ||
return ret; | return ret; | ||
} | } | ||
</ | </syntaxhighlight> | ||
===My Designer plugin isn't loaded in Designer on Windows, even though I get the complied dll and lib. What's going on?=== | ===My Designer plugin isn't loaded in Designer on Windows, even though I get the complied dll and lib. What's going on?=== | ||
You need to make sure your plugin has the same configuration as the Qt library and see if it shows up in Qt Designer http://doc.qt.io/qt-5 | You need to make sure your plugin has the same configuration as the Qt library and see if it shows up in Qt Designer http://doc.qt.io/qt-5/designer-manual.html then. When Qt is configured to build in both debug and release modes which is the default on Windows, then Qt Designer will be built in release mode, so in this case your plugin needs to be built in release mode too. When loading plugins they need to have the same configuration as the application and the Qt library that the application is using. | ||
===Why are .pro files parsed three times?=== | ===Why are .pro files parsed three times?=== | ||
Line 2,061: | Line 1,981: | ||
* Makefile.debug | * Makefile.debug | ||
* Makefile.release | * Makefile.release | ||
===On Redhat systems I get some Japanese characters displayed correctly but not all of them. How do I fix this?=== | ===On Redhat systems I get some Japanese characters displayed correctly but not all of them. How do I fix this?=== | ||
Line 2,068: | Line 1,988: | ||
without Japanese font support. The only way to fix this is to install Japanese | without Japanese font support. The only way to fix this is to install Japanese | ||
support. Then all Japanese characters should be visible just fine. | support. Then all Japanese characters should be visible just fine. | ||
===How do I get a non-rectangular or transparent widget?=== | ===How do I get a non-rectangular or transparent widget?=== | ||
Line 2,074: | Line 1,994: | ||
Warning: Non-rectangular widgets are slow on some platforms. | Warning: Non-rectangular widgets are slow on some platforms. | ||
===How can I temporarily disable tooltips in a QTreeWidget?=== | ===How can I temporarily disable tooltips in a QTreeWidget?=== | ||
You can reimplement QAbstractItemView::viewportEvent() http://doc.qt.io/qt-5/qabstractitemview.html#viewportEvent and handle the tooltip events the way you want there. Alternatively, you can install an event filter http://doc.qt.io/qt-5/qobject.html#eventFilter and handle the tooltip events there. | You can reimplement QAbstractItemView::viewportEvent() http://doc.qt.io/qt-5/qabstractitemview.html#viewportEvent and handle the tooltip events the way you want there. Alternatively, you can install an event filter http://doc.qt.io/qt-5/qobject.html#eventFilter and handle the tooltip events there. | ||
===I am unable to set a fixed size on my dialog, how can I do this?=== | ===I am unable to set a fixed size on my dialog, how can I do this?=== | ||
If your dialog does not have a layout, then you can simply call setFixedSize() http://doc.qt.io/qt-5 | If your dialog does not have a layout, then you can simply call setFixedSize() http://doc.qt.io/qt-5/qwidget.html#setFixedSize on it. If your dialog does have a layout, then you need to call | ||
< | <syntaxhighlight lang="cpp">layout()->setSizeContraint(SetFixedSize)</syntaxhighlight> | ||
This will take any changes of the size hint into consideration, i.e. when the user moves a toolbar from top to left in the window, then the fixed height will be smaller, but the fixed width will be bigger to take this into account. | This will take any changes of the size hint into consideration, i.e. when the user moves a toolbar from top to left in the window, then the fixed height will be smaller, but the fixed width will be bigger to take this into account. | ||
===I change the background color of my child widgets, but the color does not change. What's wrong?=== | ===I change the background color of my child widgets, but the color does not change. What's wrong?=== | ||
To make real subwidget transparency possible, the widgets are transparent per default. If you want to change this then you need to set autoFillBackground http://doc.qt.io/qt-5/qwidget.html#autoFillBackground-prop to true in order to allow child widgets to have a different background color than the parent. | To make real subwidget transparency possible, the widgets are transparent per default. If you want to change this then you need to set autoFillBackground http://doc.qt.io/qt-5/qwidget.html#autoFillBackground-prop to true in order to allow child widgets to have a different background color than the parent. | ||
===Building Qt with MinGW fails=== | ===Building Qt with MinGW fails=== | ||
If building Qt or Qt programs fails with something like the following errors: | If building Qt or Qt programs fails with something like the following errors: | ||
< | <syntaxhighlight>_cd tools\moc && c:/MinGW/bin/mingw32-make.exe_ | ||
_/usr/bin/sh: cd: toolsmoc: No such file or directory_</ | _/usr/bin/sh: cd: toolsmoc: No such file or directory_</syntaxhighlight> | ||
Make sure sh.exe is not in your path. make will use sh.exe instead of Windows' standard shell if sh.exe is in the path. Unfortunately sh.exe does not understand Windows-style paths and discards the '' separator. There's not much Qt can do to work around this make feature. Both Cygwin and MSYS provide sh.exe. Avoid MSYS while building Qt or Qt programs. | Make sure sh.exe is not in your path. make will use sh.exe instead of Windows' standard shell if sh.exe is in the path. Unfortunately sh.exe does not understand Windows-style paths and discards the '' separator. There's not much Qt can do to work around this make feature. Both Cygwin and MSYS provide sh.exe. Avoid MSYS while building Qt or Qt programs. | ||
===I am trying to build Qt on the Mac with the -universal flag specified, but it fails. What's wrong?=== | ===I am trying to build Qt on the Mac with the -universal flag specified, but it fails. What's wrong?=== | ||
If you are building Qt on a PowerPC you need to specify the sdk path as well | If you are building Qt on a PowerPC you need to specify the sdk path as well | ||
as the universal flag because the default libraries installed on Tiger do not | as the universal flag because the default libraries installed on Tiger do not | ||
include Intel, i.e: | include Intel, i.e: | ||
< | <syntaxhighlight> | ||
-universal -sdk /path/to/MacOSX10.4u.sdk | -universal -sdk /path/to/MacOSX10.4u.sdk | ||
</ | </syntaxhighlight> | ||
If you don't specify the sdk path on a PowerPC then it will fail giving a | If you don't specify the sdk path on a PowerPC then it will fail giving a | ||
warning like: | warning like: | ||
< | <syntaxhighlight> | ||
/usr/lib/gcc/i686-apple-darwin8/4.0.1/libstdc++.dylib does not | /usr/lib/gcc/i686-apple-darwin8/4.0.1/libstdc++.dylib does not | ||
contain an architecture that matches the specified -arch flag: i386 | contain an architecture that matches the specified -arch flag: i386 | ||
</ | </syntaxhighlight> | ||
You also need to specify the sdk in the .pro file when you are building your | You also need to specify the sdk in the .pro file when you are building your | ||
application. Add: | application. Add: | ||
< | <syntaxhighlight> | ||
QMAKE_SDK_PATH = /path/to/MacOSX10.4u.sdk | QMAKE_SDK_PATH = /path/to/MacOSX10.4u.sdk | ||
</ | </syntaxhighlight> | ||
===When using Qt with STL it crashes with a memory access exception, how do I fix this?=== | ===When using Qt with STL it crashes with a memory access exception, how do I fix this?=== | ||
If this happens, then the problem is usually either one of two things: | If this happens, then the problem is usually either one of two things: | ||
Line 2,147: | Line 2,067: | ||
right compiler. You should ensure that the environment variables match the | right compiler. You should ensure that the environment variables match the | ||
compiler that you are actually using to build and run the application. | compiler that you are actually using to build and run the application. | ||
===How can I add SSL support to my Qt application?=== | ===How can I add SSL support to my Qt application?=== | ||
Line 2,153: | Line 2,073: | ||
If you want to include SSL support, you must first obtain OpenSSL from here http://www.openssl.org/ and make sure the paths to its include and lib directories are available in the environment when building Qt. OpenSSL support should then be available by default when building Qt. | If you want to include SSL support, you must first obtain OpenSSL from here http://www.openssl.org/ and make sure the paths to its include and lib directories are available in the environment when building Qt. OpenSSL support should then be available by default when building Qt. | ||
===How can I have richtext in my QTableView?=== | ===How can I have richtext in my QTableView?=== | ||
The standard table view doesn't support rich text formatting, but you can set an item delegate on the view and reimplement its paint function so that it will allow rich text. The paint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#paint function below illustrates how this can be done and can be used with the qt\examples\itemviews\spinboxdelegate example http://doc.qt.io/qt-5/4.7/itemviews-spinboxdelegate.html : | The standard table view doesn't support rich text formatting, but you can set an item delegate on the view and reimplement its paint function so that it will allow rich text. The paint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#paint function below illustrates how this can be done and can be used with the qt\examples\itemviews\spinboxdelegate example http://doc.qt.io/qt-5/4.7/itemviews-spinboxdelegate.html : | ||
< | <syntaxhighlight lang="cpp"> | ||
void SpinBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const | void SpinBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const | ||
{ | { | ||
Line 2,175: | Line 2,095: | ||
} | } | ||
</ | </syntaxhighlight> | ||
You can find more information on the text formatting in our documentation http://doc.qt.io/qt-5/richtext-html-subset.html | You can find more information on the text formatting in our documentation http://doc.qt.io/qt-5/richtext-html-subset.html | ||
===Can I use Windows APIs together with Qt? The compiler complains about redefinition of HDC etc.=== | ===Can I use Windows APIs together with Qt? The compiler complains about redefinition of HDC etc.=== | ||
Line 2,186: | Line 2,106: | ||
the Qt header files before windows.h or any other Windows header files in your | the Qt header files before windows.h or any other Windows header files in your | ||
code. | code. | ||
===Is there a limit to the number of widgets I can create on Windows ?=== | ===Is there a limit to the number of widgets I can create on Windows ?=== | ||
Line 2,205: | Line 2,125: | ||
use of these types of objects, such as deleting dialogs immediatly after they | use of these types of objects, such as deleting dialogs immediatly after they | ||
have been used and hidden, etc. | have been used and hidden, etc. | ||
===A QTreeWidget is sorted alphabetically by default, how can I change this behavior, e.g to sort numerically instead ?=== | ===A QTreeWidget is sorted alphabetically by default, how can I change this behavior, e.g to sort numerically instead ?=== | ||
You can achieve this by subclassing QTreeWidgetItem and reimplementing QTreeWidgetItem::operator<() http://doc.qt.io/qt-5/qtreewidgetitem.html#operator-lt to perform e.g numeric sorting rather than string comparison. | You can achieve this by subclassing QTreeWidgetItem and reimplementing QTreeWidgetItem::operator<() http://doc.qt.io/qt-5/qtreewidgetitem.html#operator-lt to perform e.g numeric sorting rather than string comparison. | ||
Note that setSortingEnabled http://doc.qt.io/qt-5 | Note that setSortingEnabled http://doc.qt.io/qt-5/qtreeview.html#sortingEnabled-prop should be set to true after you insert the items, otherwise the insertion will be slow as each item that gets inserted will get sorted. Alternatively, you can insert all of the items in one go using a list, see: | ||
http://doc.qt.io/qt-5/qtreewidget.html#insertTopLevelItems | http://doc.qt.io/qt-5/qtreewidget.html#insertTopLevelItems | ||
Line 2,216: | Line 2,136: | ||
The following example illustrates how this can be done: | The following example illustrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class TreeWidgetItem : public QTreeWidgetItem | class TreeWidgetItem : public QTreeWidgetItem | ||
{ | { | ||
public: | public: | ||
TreeWidgetItem(QTreeWidget *tree) : QTreeWidgetItem(tree) {} | TreeWidgetItem(QTreeWidget *tree) : QTreeWidgetItem(tree) {} | ||
TreeWidgetItem(QTreeWidget * parent, const QStringList & strings) | TreeWidgetItem(QTreeWidget * parent, const QStringList & strings) | ||
: QTreeWidgetItem (parent,strings) {} | : QTreeWidgetItem (parent,strings) {} | ||
bool operator< (const QTreeWidgetItem &other) const | bool operator< (const QTreeWidgetItem &other) const | ||
{ | { | ||
int sortCol = treeWidget()->sortColumn(); | int sortCol = treeWidget()->sortColumn(); | ||
int myNumber = text(sortCol).toInt(); | int myNumber = text(sortCol).toInt(); | ||
int otherNumber = other.text(sortCol).toInt(); | int otherNumber = other.text(sortCol).toInt(); | ||
return myNumber < otherNumber; | return myNumber < otherNumber; | ||
} | } | ||
}; | }; | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
QTreeWidget tree; | QTreeWidget tree; | ||
tree.setColumnCount(2); | tree.setColumnCount(2); | ||
TreeWidgetItem *item1 = new TreeWidgetItem(&tree); | TreeWidgetItem *item1 = new TreeWidgetItem(&tree); | ||
item1->setText(0, "1"); | item1->setText(0, "1"); | ||
TreeWidgetItem *item2 = new TreeWidgetItem(&tree); | TreeWidgetItem *item2 = new TreeWidgetItem(&tree); | ||
item2->setText(0, "2"); | item2->setText(0, "2"); | ||
TreeWidgetItem *item3 = new TreeWidgetItem(&tree); | TreeWidgetItem *item3 = new TreeWidgetItem(&tree); | ||
item3->setText(0, "3"); | item3->setText(0, "3"); | ||
QStringList list; | QStringList list; | ||
list << "10" << "6"; | list << "10" << "6"; | ||
TreeWidgetItem *item4 = new TreeWidgetItem(&tree, list); | TreeWidgetItem *item4 = new TreeWidgetItem(&tree, list); | ||
QStringList list2; | QStringList list2; | ||
list2 << "20" << "7"; | list2 << "20" << "7"; | ||
TreeWidgetItem *item5 = new TreeWidgetItem(&tree, list2); | TreeWidgetItem *item5 = new TreeWidgetItem(&tree, list2); | ||
tree.setSortingEnabled(true); | tree.setSortingEnabled(true); | ||
tree.show(); | tree.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Are there any books about Qt programming?=== | ===Are there any books about Qt programming?=== | ||
Line 2,261: | Line 2,181: | ||
amazon.com. Check out the Qt Book list to find a list of known available Qt | amazon.com. Check out the Qt Book list to find a list of known available Qt | ||
books. | books. | ||
===How can I change the border color of a frame using a stylesheet?=== | ===How can I change the border color of a frame using a stylesheet?=== | ||
In order to change the border color, you need to specify a px size in the stylesheet http://doc.qt.io/qt-5 | In order to change the border color, you need to specify a px size in the stylesheet http://doc.qt.io/qt-5/stylesheet.html, e.g | ||
< | <syntaxhighlight lang="cpp"> | ||
browser->setStyleSheet("QTextBrowser {border: 1px solid red}"); | browser->setStyleSheet("QTextBrowser {border: 1px solid red}"); | ||
</ | </syntaxhighlight> | ||
The border is 0px by default, so in order for it to show up, you need to define a px size. | The border is 0px by default, so in order for it to show up, you need to define a px size. | ||
===There are general rendering problems when I run my application on a machine that has a Matrox G450 graphics card. Other machines that don't use this card do not have this problem. Is there a way to workaround this?=== | ===There are general rendering problems when I run my application on a machine that has a Matrox G450 graphics card. Other machines that don't use this card do not have this problem. Is there a way to workaround this?=== | ||
Line 2,280: | Line 2,200: | ||
Bitmap Device Caching**. Disabling this should resolve the problem with the | Bitmap Device Caching**. Disabling this should resolve the problem with the | ||
rendering. | rendering. | ||
===I want to pop up a menu when I get a mouse event, but the menu pops up at wild places. (How do I convert local coordinates to global ones?)=== | ===I want to pop up a menu when I get a mouse event, but the menu pops up at wild places. (How do I convert local coordinates to global ones?)=== | ||
The QPoint() http://doc.qt.io/qt-5 | The QPoint() http://doc.qt.io/qt-5/qpoint.html argument to the popup() http://doc.qt.io/qt-5/qmenu.html#popup function takes global screen coordinates as its argument. The position sent to a mouse event is always in the widgets local coordinates. Positions can be transformed between the different coordinate systems with either: | ||
* QWidget::mapToGlobal() http://doc.qt.io/qt-5 | * QWidget::mapToGlobal() http://doc.qt.io/qt-5/qwidget.html#mapToGlobal | ||
* QWidget::mapToParent() http://doc.qt.io/qt-5 | * QWidget::mapToParent() http://doc.qt.io/qt-5/qwidget.html#mapToParent | ||
* QWidget::mapFromGlobal() http://doc.qt.io/qt-5 | * QWidget::mapFromGlobal() http://doc.qt.io/qt-5/qwidget.html#mapFromGlobal | ||
* QWidget::mapFromParent() http://doc.qt.io/qt-5 | * QWidget::mapFromParent() http://doc.qt.io/qt-5/qwidget.html#mapFromParent | ||
In the case with the mouse event, the correct way is to use the event's globalPos() http://doc.qt.io/qt-5 | In the case with the mouse event, the correct way is to use the event's globalPos() http://doc.qt.io/qt-5/qmouseevent.html#globalPos function instead. Here is one way of doing it: | ||
< | <syntaxhighlight lang="cpp"> | ||
void CustomWidget::mousePressEvent(QMouseEvent *event) | void CustomWidget::mousePressEvent(QMouseEvent *event) override | ||
{ | { | ||
if (event->button() == RightButton) | if (event->button() == RightButton) | ||
menu->popup(event->globalPos()); | menu->popup(event->globalPos()); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===You frequently say that you cannot add this or that feature because it would break binary compatibility. What does this mean, really?=== | ===You frequently say that you cannot add this or that feature because it would break binary compatibility. What does this mean, really?=== | ||
Line 2,331: | Line 2,251: | ||
* We cannot change the signature of a function, this includes changing the | * We cannot change the signature of a function, this includes changing the | ||
return type and adding a new parameter. | return type and adding a new parameter. | ||
===How can I generate .vcproj files recursively for a .pro file with the SUBDIRS template set?=== | ===How can I generate .vcproj files recursively for a .pro file with the SUBDIRS template set?=== | ||
You can create .vcproj files recursively by typing | You can create .vcproj files recursively by typing | ||
< | <syntaxhighlight> qmake -tp vc -r</syntaxhighlight> | ||
in the toplevel directory. Then the .vcproj files will be created in each subdirectory and the .sln file will be created in the main directory. | in the toplevel directory. Then the .vcproj files will be created in each subdirectory and the .sln file will be created in the main directory. | ||
===How can I get a HDC handle?=== | ===How can I get a HDC handle?=== | ||
You can create a HBITMAP using GDI and then you can convert this to a QPixmap http://doc.qt.io/qt-5 | You can create a HBITMAP using GDI and then you can convert this to a QPixmap http://doc.qt.io/qt-5/qpixmap.html afterwards. See the documentation http://doc.qt.io/qt-5/qpixmap.html#fromWinHBITMAP for more information on how to do that. | ||
===MSVCRTD.lib(cinitexe.obj) : warning LNK4098: defaultlib msvcrt.lib conflicts with use of other libs; use /NODEFAULTLIB:library -- What does this mean and how can I fix it?=== | ===MSVCRTD.lib(cinitexe.obj) : warning LNK4098: defaultlib msvcrt.lib conflicts with use of other libs; use /NODEFAULTLIB:library -- What does this mean and how can I fix it?=== | ||
Line 2,349: | Line 2,269: | ||
and your application is built with debug symbols. You need to rebuild Qt in | and your application is built with debug symbols. You need to rebuild Qt in | ||
debug mode or the application in release mode. | debug mode or the application in release mode. | ||
===Is there a way to work around the fact that the dockwindow is only hidden and not closed?=== | ===Is there a way to work around the fact that the dockwindow is only hidden and not closed?=== | ||
It is intentional that the dockwindow is hidden and not closed. You can delete the dockwindow by calling close() http://doc.qt.io/qt-5 | It is intentional that the dockwindow is hidden and not closed. You can delete the dockwindow by calling close() http://doc.qt.io/qt-5/qwidget.html#close in the hideEvent() http://doc.qt.io/qt-5/qwidget.html#hideEvent in addition to passing in the Qt::WA_DeleteOnClose http://doc.qt.io/qt-5/qt.html#WidgetAttribute-enum attribute. Another approach could be to call deleteLater() http://doc.qt.io/qt-5/qobject.html#deleteLater in the hideEvent(). You can not delete it in the hideEvent() as this will cause a crash. | ||
===Is there a limitation on Windows as to how many QRegions we can have?=== | ===Is there a limitation on Windows as to how many QRegions we can have?=== | ||
Qt itself does not impose a limit on the number of QRegions http://doc.qt.io/qt-5 | Qt itself does not impose a limit on the number of QRegions http://doc.qt.io/qt-5/qregion.html, however since QRegion uses a GDI object on Windows, you are limited by the amount of GDI resources that are available to you on Windows. This varies depending on what version of Windows you are using. | ||
===How can I create a QDialog that has no minimize, maximize and close buttons in the titlebar?=== | ===How can I create a QDialog that has no minimize, maximize and close buttons in the titlebar?=== | ||
Line 2,365: | Line 2,285: | ||
< | <syntaxhighlight> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
Line 2,374: | Line 2,294: | ||
box.show(); | box.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I maintain several configurations using only one source tree?=== | ===How can I maintain several configurations using only one source tree?=== | ||
This can be done by using shadow builds. Start with a clean Qt source directory. Create a folder for your custom configuration, and call configure from this directory using | This can be done by using shadow builds. Start with a clean Qt source directory. Create a folder for your custom configuration, and call configure from this directory using | ||
< | <syntaxhighlight>../path/to/qtdir/configure -prefix $PWD <other options here></syntaxhighlight> | ||
This will allow you to maintain several configurations for one source. | This will allow you to maintain several configurations for one source. | ||
===My underlines for accelerators don't show up in the context menus when I press Alt, while they do for normal menus. What's wrong?=== | ===My underlines for accelerators don't show up in the context menus when I press Alt, while they do for normal menus. What's wrong?=== | ||
Line 2,394: | Line 2,314: | ||
Check this if you want the underlines to be displayed at all times. You will see the same behavior in e.g notepad | Check this if you want the underlines to be displayed at all times. You will see the same behavior in e.g notepad | ||
===How to build pdb for release version of Qt?=== | ===How to build pdb for release version of Qt?=== | ||
In order to build .pdb files for the release version of Qt, simply add the required compiler parameter in the mkspec you use. For example for MSVC 2005, you'd modify <Qt path>\mkspecs\win32-msvc2005\qmake.conf and add the -zi flag to QMAKE_CFLAGS_RELEASE and the /DEBUG flag to QMAKE_LFLAGS_RELEASE, e.g | In order to build .pdb files for the release version of Qt, simply add the required compiler parameter in the mkspec you use. For example for MSVC 2005, you'd modify <Qt path>\mkspecs\win32-msvc2005\qmake.conf and add the -zi flag to QMAKE_CFLAGS_RELEASE and the /DEBUG flag to QMAKE_LFLAGS_RELEASE, e.g | ||
< | <syntaxhighlight>QMAKE_CFLAGS_RELEASE = -O2 -MD -zi</syntaxhighlight> | ||
and | and | ||
< | <syntaxhighlight>QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO /DEBUG </syntaxhighlight> | ||
Now the compiler will create debug information and the linker will use it while linking. | Now the compiler will create debug information and the linker will use it while linking. | ||
===Do you provide a tool for creating graphs?=== | ===Do you provide a tool for creating graphs?=== | ||
Line 2,422: | Line 2,342: | ||
http://sourceforge.net/projects/qwt/ | http://sourceforge.net/projects/qwt/ | ||
http://www.kdab.com/products/kd-chart | http://www.kdab.com/products/kd-chart | ||
===I am unable to step into the Qt code in Visual Studio, what can the problem be?=== | ===I am unable to step into the Qt code in Visual Studio, what can the problem be?=== | ||
Line 2,431: | Line 2,351: | ||
The other situation where the debugging would not work is when something is out of sync. You are using some libraries from previous builds for example. The best thing to do in this case is to clean out the old build by going to a command prompt and typing | The other situation where the debugging would not work is when something is out of sync. You are using some libraries from previous builds for example. The best thing to do in this case is to clean out the old build by going to a command prompt and typing | ||
< | <syntaxhighlight>nmake clean | ||
configure -redo | configure -redo | ||
nmake</ | nmake</syntaxhighlight> | ||
in your Qt directory. | in your Qt directory. | ||
===Why do ActiveQt controls no longer work after an upgrade to Internet Explorer 7?=== | ===Why do ActiveQt controls no longer work after an upgrade to Internet Explorer 7?=== | ||
The reason this happens is because Internet Explorer 7 has changed the security settings around. In order to make ActiveQt controls work in Internet Explorer you need to add the website that hosts the control to your *Trusted Sites* and *Enable Scripting For Unsigned Controls* for the Trusted Sites security level. | The reason this happens is because Internet Explorer 7 has changed the security settings around. In order to make ActiveQt controls work in Internet Explorer you need to add the website that hosts the control to your *Trusted Sites* and *Enable Scripting For Unsigned Controls* for the Trusted Sites security level. | ||
===Do you support using Qt in the Cygwin shell on Windows?=== | ===Do you support using Qt in the Cygwin shell on Windows?=== | ||
Line 2,446: | Line 2,366: | ||
different directory separators than the Windows ones, therefore our apps are | different directory separators than the Windows ones, therefore our apps are | ||
not likely to work correctly. You should use the cmd shell instead. | not likely to work correctly. You should use the cmd shell instead. | ||
===When untaring the Qt package the following warning is seen Tar.gz file content file @Longlink with zero permission and size. How can this be resolved?=== | ===When untaring the Qt package the following warning is seen Tar.gz file content file @Longlink with zero permission and size. How can this be resolved?=== | ||
When untarring the Qt package with a different version of tar that is not the GNU tar, then the warning: | When untarring the Qt package with a different version of tar that is not the GNU tar, then the warning: | ||
< | <syntaxhighlight>Tar.gz file content file @Longlink with zero permission and size</syntaxhighlight> | ||
may be seen. This is because LongLink is used when creating the package and this is an extension to GNU's tar to allow filenames longer than 100 characters. Therefore the package can only be used with the GNU version of tar, not with the vendor version of tar. | may be seen. This is because LongLink is used when creating the package and this is an extension to GNU's tar to allow filenames longer than 100 characters. Therefore the package can only be used with the GNU version of tar, not with the vendor version of tar. | ||
===The font Rendering is distorted on Windows, what could cause this problem?=== | ===The font Rendering is distorted on Windows, what could cause this problem?=== | ||
Ensure that ClearType is enabled in Windows display properties. The location of the ClearType check box depends on which version of Windows is being used. | Ensure that ClearType is enabled in Windows display properties. The location of the ClearType check box depends on which version of Windows is being used. | ||
===When I compile my Qt based program I get a parse/syntax error in one of Qt's header files. What's wrong?=== | ===When I compile my Qt based program I get a parse/syntax error in one of Qt's header files. What's wrong?=== | ||
Line 2,476: | Line 2,396: | ||
* Include the other header files, then #undef the relevant macro, then include the Qt header files. For example: | * Include the other header files, then #undef the relevant macro, then include the Qt header files. For example: | ||
</ | </syntaxhighlight> | ||
#define ButtonMask ButtonMask_hack | #define ButtonMask ButtonMask_hack | ||
#include <offender.h> | #include <offender.h> | ||
#undef ButtonMask | #undef ButtonMask | ||
#include <qmsgbox.h> | #include <qmsgbox.h> | ||
</ | </syntaxhighlight> | ||
This allows you to use the function or enum in Qt, but not the macro in the | This allows you to use the function or enum in Qt, but not the macro in the | ||
other header file. | other header file. | ||
Line 2,494: | Line 2,414: | ||
with Qt's global color objects named red and black. Here's a workaround: | with Qt's global color objects named red and black. Here's a workaround: | ||
< | <syntaxhighlight lang="cpp"> | ||
#define red stl_red | #define red stl_red | ||
#define black stl_black | #define black stl_black | ||
Line 2,501: | Line 2,421: | ||
#undef black | #undef black | ||
#include <qcolor.h> | #include <qcolor.h> | ||
</ | </syntaxhighlight> | ||
===How is configuration management handled?=== | ===How is configuration management handled?=== | ||
Line 2,509: | Line 2,429: | ||
encapsulated in a simple 'project' file (eg. listing files appropriate for | encapsulated in a simple 'project' file (eg. listing files appropriate for | ||
given configurations). | given configurations). | ||
===Why does a statically built Qt use the dynamic Visual Studio runtime libraries ? Do I need to deploy those with my application ?=== | ===Why does a statically built Qt use the dynamic Visual Studio runtime libraries ? Do I need to deploy those with my application ?=== | ||
Line 2,517: | Line 2,437: | ||
If you choose to change this setting anyway, then it can be done in the qmake.conf file for your qmakespec. Where it says *-MD* you need to change it to be *-MT*. For Visual Studio 2005 it is also necessary to change the relevant files in mkspecs/features to remove the call to mt.exe. As stated above, we can't support you with any problems you run into as a consequence of making these changes. | If you choose to change this setting anyway, then it can be done in the qmake.conf file for your qmakespec. Where it says *-MD* you need to change it to be *-MT*. For Visual Studio 2005 it is also necessary to change the relevant files in mkspecs/features to remove the call to mt.exe. As stated above, we can't support you with any problems you run into as a consequence of making these changes. | ||
===What do I need installed on my machine to begin using Qt Creator and/or the Qt SDK?=== | ===What do I need installed on my machine to begin using Qt Creator and/or the Qt SDK?=== | ||
Line 2,527: | Line 2,447: | ||
* Mac: Standard development tools like debugger, etc. The easiest way to get these is to install XCode. | * Mac: Standard development tools like debugger, etc. The easiest way to get these is to install XCode. | ||
===When I read a XPM image into a QImage, is there a way I get determine which color is the transparent one?=== | ===When I read a XPM image into a QImage, is there a way I get determine which color is the transparent one?=== | ||
You can have a look at the color table for the image. This is accessible through QImage::color() http://doc.qt.io/qt-5//qimage.html#color and then you can check for colors that have an alpha of 0. | You can have a look at the color table for the image. This is accessible through QImage::color() http://doc.qt.io/qt-5//qimage.html#color and then you can check for colors that have an alpha of 0. | ||
===How do I find out the properties of my Linux Frame Buffer?=== | ===How do I find out the properties of my Linux Frame Buffer?=== | ||
Use the Linux command: *fbset*, often found in /usr/sbin/. | Use the Linux command: *fbset*, often found in /usr/sbin/. | ||
===How can I find out where the contents of my Mac binary package is installed?=== | ===How can I find out where the contents of my Mac binary package is installed?=== | ||
Line 2,545: | Line 2,465: | ||
directory and doing a lsbom on Archive.bom in that directory. | directory and doing a lsbom on Archive.bom in that directory. | ||
===How can I create a custom editor in my view?=== | ===How can I create a custom editor in my view?=== | ||
You can create a delegate and set it on the view using setItemDelegate() http://doc.qt.io/qt-5/qabstractitemview.html#setItemDelegate. A delegate http://doc.qt.io/qt-5 | You can create a delegate and set it on the view using setItemDelegate() http://doc.qt.io/qt-5/qabstractitemview.html#setItemDelegate. A delegate http://doc.qt.io/qt-5/qstyleditemdelegate.html allows the way items of data are rendered and edited to be customized. | ||
Alternatively you can use QItemEditorCreatorBase http://doc.qt.io/qt-5/qitemeditorcreatorbase.html. | Alternatively you can use QItemEditorCreatorBase http://doc.qt.io/qt-5/qitemeditorcreatorbase.html. | ||
See the spinboxdelegate http://doc.qt.io/qt-5 | See the spinboxdelegate http://doc.qt.io/qt-5/itemviews-spinboxdelegate.html example for a demonstration on how to implement your delegate. | ||
===Purify complains about UMRs (Uninitialized Memory Reads) in the QGDict constructor? Is this a bug in Qt?=== | ===Purify complains about UMRs (Uninitialized Memory Reads) in the QGDict constructor? Is this a bug in Qt?=== | ||
Line 2,575: | Line 2,495: | ||
We've been in contact with PureAtria (now Rational), the maker of Purify, and they say this is a problem which cannot easily be solved. The only solution would be that the compiler first sets all bytes to zero before accessing the bits. | We've been in contact with PureAtria (now Rational), the maker of Purify, and they say this is a problem which cannot easily be solved. The only solution would be that the compiler first sets all bytes to zero before accessing the bits. | ||
===How is your double buffering implemented?=== | ===How is your double buffering implemented?=== | ||
We use an approach commonly referred to as backing store. In this technique we maintain one pixmap per toplevel widget and each widget draws itself into this pixmap. Only when a widget changes does it update the contents of the toplevel pixmap. The effect of this is that on expose events the windowing system (or Qt) can copy the pixmap to screen rather than calling QWidget::paintEvent() (which can be costly), resulting in very fast updates when windows are moving on top of each other. | We use an approach commonly referred to as backing store. In this technique we maintain one pixmap per toplevel widget and each widget draws itself into this pixmap. Only when a widget changes does it update the contents of the toplevel pixmap. The effect of this is that on expose events the windowing system (or Qt) can copy the pixmap to screen rather than calling QWidget::paintEvent() (which can be costly), resulting in very fast updates when windows are moving on top of each other. | ||
===Is Qt binary compatible?=== | ===Is Qt binary compatible?=== | ||
Qt is backwards binary and source compatible within each major release. This means that a program linked dynamically to e.g Qt 4.5.1 will continue running with Qt 4.5.3 without the need to recompile. Qt is not binary compatible between major versions such as Qt 2.x, Qt 3.x and Qt 4.x etc. Qt is also not forwards compatible, meaning that applications created with a newer version of Qt will not necessarily run or compile against older Qt versions. | Qt is backwards binary and source compatible within each major release. This means that a program linked dynamically to e.g Qt 4.5.1 will continue running with Qt 4.5.3 without the need to recompile. Qt is not binary compatible between major versions such as Qt 2.x, Qt 3.x and Qt 4.x etc. Qt is also not forwards compatible, meaning that applications created with a newer version of Qt will not necessarily run or compile against older Qt versions. | ||
===How can I find out what image formats my application supports?=== | ===How can I find out what image formats my application supports?=== | ||
Line 2,599: | Line 2,519: | ||
Another alternative is to use an alpha color on the pen instead of a dotted | Another alternative is to use an alpha color on the pen instead of a dotted | ||
line. This will be visually different, but usually looks as nice. | line. This will be visually different, but usually looks as nice. | ||
===How can I paint outside the paintevent?=== | ===How can I paint outside the paintevent?=== | ||
Line 2,607: | Line 2,527: | ||
do instead is to do all your drawing to a QPixmap and draw this pixmap as part | do instead is to do all your drawing to a QPixmap and draw this pixmap as part | ||
of your paint event. | of your paint event. | ||
===How can I resize a QDockWidget programatically?=== | ===How can I resize a QDockWidget programatically?=== | ||
When you add the dock widget to the QMainWindow http://doc.qt.io/qt-5 | When you add the dock widget to the QMainWindow http://doc.qt.io/qt-5/qmainwindow.html, it becomes part of the main window's layout and any size you give is ignored. You can however reimplement the QWidget::sizeHint() http://doc.qt.io/qt-5/qwidget.html#sizeHint-prop for the widget contained in the QDockWidget http://doc.qt.io/qt-5/qdockwidget.html to give it a preferred size or you can call QWidget::setFixedSize() http://doc.qt.io/qt-5/qwidget.html#setFixedSize on it to give it a size that can't be changed. | ||
Note that since QDockWidget acts as a wrapper for its child widget, custom size hints, minimum and maximum sizes and size policies have to be implemented in the child widget. QDockWidget will respect them, adjusting its own constraints to include the frame and title. Size constraints should not be set on the QDockWidget itself, because they change depending on whether it is docked; a docked QDockWidget has no frame and a smaller title bar. | Note that since QDockWidget acts as a wrapper for its child widget, custom size hints, minimum and maximum sizes and size policies have to be implemented in the child widget. QDockWidget will respect them, adjusting its own constraints to include the frame and title. Size constraints should not be set on the QDockWidget itself, because they change depending on whether it is docked; a docked QDockWidget has no frame and a smaller title bar. | ||
See the following example for a demonstration: | See the following example for a demonstration: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Label : public QLabel | class Label : public QLabel | ||
{ | { | ||
public: | public: | ||
Label(QWidget *parent) : QLabel(parent) | Label(QWidget *parent) : QLabel(parent) | ||
{ | { | ||
setAutoFillBackground(true); | setAutoFillBackground(true); | ||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); | setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); | ||
QPalette pal = palette(); | QPalette pal = palette(); | ||
pal.setBrush(QPalette::Window, Qt::red); | pal.setBrush(QPalette::Window, Qt::red); | ||
setText("The label"); | setText("The label"); | ||
setPalette(pal); | setPalette(pal); | ||
} | } | ||
QSize sizeHint() const | QSize sizeHint() const | ||
{ | { | ||
return QSize(400, 500); | return QSize(400, 500); | ||
} | } | ||
}; | }; | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
QMainWindow box; | QMainWindow box; | ||
box.setCentralWidget(new QLabel("Central Widget", &box)); | box.setCentralWidget(new QLabel("Central Widget", &box)); | ||
QDockWidget *dock = new QDockWidget(&box); | QDockWidget *dock = new QDockWidget(&box); | ||
dock->setWidget(new Label(dock)); | dock->setWidget(new Label(dock)); | ||
box.addDockWidget(Qt::TopDockWidgetArea, dock ); | box.addDockWidget(Qt::TopDockWidgetArea, dock ); | ||
box.show(); | box.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===When I build Qt I see the following: *** [listboxeditor.h] Trace/BPT trap and it fails to build.=== | ===When I build Qt I see the following: *** [listboxeditor.h] Trace/BPT trap and it fails to build.=== | ||
This is because your DYLD_LIBRARY_PATH is not set correctly, it needs to | This is because your DYLD_LIBRARY_PATH is not set correctly, it needs to | ||
include the $QTDIR/lib directory. | include the $QTDIR/lib directory. | ||
===How can I add widgets to my QFileDialog instance?=== | ===How can I add widgets to my QFileDialog instance?=== | ||
Line 2,660: | Line 2,580: | ||
your widgets there. See the following example: | your widgets there. See the following example: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
Line 2,674: | Line 2,594: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I draw text that is both filled and outlined?=== | ===How can I draw text that is both filled and outlined?=== | ||
If you want to draw text both filled and outlined, you can use QPainterPath http://doc.qt.io/qt-5 | If you want to draw text both filled and outlined, you can use QPainterPath http://doc.qt.io/qt-5/qpainterpath.html for this, for instance: | ||
< | <syntaxhighlight lang="cpp"> | ||
QPainterPath path; | QPainterPath path; | ||
path.addText(position, font, "Hello"); | path.addText(position, font, "Hello"); | ||
Line 2,687: | Line 2,607: | ||
painter.drawPath(path); | painter.drawPath(path); | ||
</ | </syntaxhighlight> | ||
===Purify found a memory leak in qapplication_x11.cpp. Why don't you clean up the XIM (X Input Method) structure?=== | ===Purify found a memory leak in qapplication_x11.cpp. Why don't you clean up the XIM (X Input Method) structure?=== | ||
This is to work around a bug in some versions of Xlib. The leak isn't harmful, it concerns only 400 bytes of memory which will be deallocated anyway when the application terminates. | This is to work around a bug in some versions of Xlib. The leak isn't harmful, it concerns only 400 bytes of memory which will be deallocated anyway when the application terminates. | ||
===You say I can program for multiple platforms with one source tree with Qt. Do I need cross-compilers or special tools?=== | ===You say I can program for multiple platforms with one source tree with Qt. Do I need cross-compilers or special tools?=== | ||
Line 2,699: | Line 2,619: | ||
targeted platforms. There is no need for special cross-compilers or additional | targeted platforms. There is no need for special cross-compilers or additional | ||
tools. | tools. | ||
===Are any benchmarking and performance measurement tools used?=== | ===Are any benchmarking and performance measurement tools used?=== | ||
We use a combination of complete instrumented quantification (Valgrind/ | We use a combination of complete instrumented quantification (Valgrind/ | ||
Cachegrind) and specific manual instrumentation (event timing). | Cachegrind) and specific manual instrumentation (event timing). | ||
===Why can't Qt Mac for Cocoa be configured with -static?=== | ===Why can't Qt Mac for Cocoa be configured with -static?=== | ||
Line 2,717: | Line 2,637: | ||
===unixODBC FreeTDS qGetStringData: Error while fetching data=== | ===unixODBC FreeTDS qGetStringData: Error while fetching data=== | ||
When installing unixODBC 2.2.14 and freeTDS 0.82 and executing a query like | When installing unixODBC 2.2.14 and freeTDS 0.82 and executing a query like | ||
< | <syntaxhighlight> select USER_ID from MY_TABLE </syntaxhighlight> | ||
the following message will be issued: | the following message will be issued: | ||
< | <syntaxhighlight>qGetStringData: Error while fetching data ( [FreeTDS][SQL Server]Program type out of range )</syntaxhighlight> | ||
The solution to this problem is to install the latest version of FreeTDS, as it now provides SQL W CHAR. | The solution to this problem is to install the latest version of FreeTDS, as it now provides SQL W CHAR. | ||
===Why is my text not antialiased?=== | ===Why is my text not antialiased?=== | ||
Text antialiasing in Qt is based on the underlying font system. If a font is not being antialiased it is most likely because it is a bitmap font or because the underlying system does not support it. On X11 for instance, Xft is required to draw antialised fonts. | Text antialiasing in Qt is based on the underlying font system. If a font is not being antialiased it is most likely because it is a bitmap font or because the underlying system does not support it. On X11 for instance, Xft is required to draw antialised fonts. | ||
It is possible to specify a style strategy to QFont http://doc.qt.io/qt-5 | It is possible to specify a style strategy to QFont http://doc.qt.io/qt-5/qfont.html, using QFont::StyleStrategy http://doc.qt.io/qt-5/qfont.html#StyleStrategy-enum, which can be a hint to tell the font not to use a bitmap font. Depending on the fonts available on the system and the font family specified, this may or may not work. | ||
On Windows 2000 fonts are usually not antialiased within a certain range (say sizes 8-16) to make text more crisp and readable. | On Windows 2000 fonts are usually not antialiased within a certain range (say sizes 8-16) to make text more crisp and readable. | ||
===How can a QModelIndex be retrived from the model for an internal data item?=== | ===How can a QModelIndex be retrived from the model for an internal data item?=== | ||
Line 2,781: | Line 2,701: | ||
argument, and you should get the QModelIndex for your item. Please consider | argument, and you should get the QModelIndex for your item. Please consider | ||
that in a worst case scenario you will traverse the whole data model. | that in a worst case scenario you will traverse the whole data model. | ||
===How to avoid subclassing all available styles when wanting to change a small aspect of a widget for all styles=== | ===How to avoid subclassing all available styles when wanting to change a small aspect of a widget for all styles=== | ||
Since Qt 4.6 you can use QProxyStyle: https://doc.qt.io/qt-5/qproxystyle.html | |||
===How do I create tooltips in QHeaderView?=== | ===How do I create tooltips in QHeaderView?=== | ||
It is possible to create tooltips for each header in a model by setting its Qt::ToolTipRole http://doc.qt.io/qt-5 | It is possible to create tooltips for each header in a model by setting its Qt::ToolTipRole http://doc.qt.io/qt-5/qt.html#ItemDataRole-enum | ||
< | <syntaxhighlight lang="cpp"> | ||
QStandardItemModel model ; | QStandardItemModel model ; | ||
model.setRowCount(5); | model.setRowCount(5); | ||
Line 2,881: | Line 2,715: | ||
model.setHeaderData ( 1, Qt::Horizontal, QVariant("test"), Qt::ToolTipRole ); | model.setHeaderData ( 1, Qt::Horizontal, QVariant("test"), Qt::ToolTipRole ); | ||
model.setHeaderData ( 1, Qt::Horizontal, QVariant("Column 2"), Qt::DisplayRole ); | model.setHeaderData ( 1, Qt::Horizontal, QVariant("Column 2"), Qt::DisplayRole ); | ||
</ | </syntaxhighlight> | ||
===How can I make Designer look for plugins outside qtDirectory\plugins\designer=== | ===How can I make Designer look for plugins outside qtDirectory\plugins\designer=== | ||
You can make designer look for plugins elsewhere using the QT_PLUGIN_PATH http://doc.qt.io/qt-5/qcoreapplication.html#libraryPaths environment variable. | You can make designer look for plugins elsewhere using the QT_PLUGIN_PATH http://doc.qt.io/qt-5/qcoreapplication.html#libraryPaths environment variable. | ||
Note that your plugins need to be a in a designer subdirectory inside the path that | Note that your plugins need to be a in a designer subdirectory inside the path that | ||
Line 2,891: | Line 2,725: | ||
===How can I change the width of the popup list in my combobox?=== | ===How can I change the width of the popup list in my combobox?=== | ||
In order to change the width of the combobox's view, you can subclass QComboBox http://doc.qt.io/qt-5 | In order to change the width of the combobox's view, you can subclass QComboBox http://doc.qt.io/qt-5/qcombobox.html and reimplement showPopup() http://doc.qt.io/qt-5/qcombobox.html#showPopup to set the width you want on the view. | ||
See the following example for an indication of how to do this: | See the following example for an indication of how to do this: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include <QApplication> | #include <QApplication> | ||
#include <QComboBox> | #include <QComboBox> | ||
Line 2,928: | Line 2,762: | ||
box.show(); | box.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I have both text and a pixmap on a QLabel?=== | ===How can I have both text and a pixmap on a QLabel?=== | ||
This is not possible to achieve with the QLabel http://doc.qt.io/qt-5 | This is not possible to achieve with the QLabel http://doc.qt.io/qt-5/qlabel.html API directly, but you can use richtext to make this work. See the following example: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
Line 2,943: | Line 2,777: | ||
label.show(); | label.show(); | ||
return app.exec(); | return app.exec(); | ||
</ | </syntaxhighlight> | ||
===How can I avoid a paintEvent() when focus changes on Windows ?=== | ===How can I avoid a paintEvent() when focus changes on Windows ?=== | ||
The trick is to block activate/inactive events. See the example below for a demonstration. Note that it is necessary to set the WA_OpaquePaintEvent http://doc.qt.io/qt-5 | The trick is to block activate/inactive events. See the example below for a demonstration. Note that it is necessary to set the WA_OpaquePaintEvent http://doc.qt.io/qt-5/qt.html#WidgetAttribute-enum attribute since widgets are defined to be transparent by default. This has been done to allow widgets to have features like antialiased round edges and sub widget transparency. A transparent widget needs to be updated when its parent is updated because an update in the parent will effect the child widget as well. This also applies to palette changes. | ||
By setting the WA_OpaquePaintEvent the widget is no longer transparent and no longer subject to updates as a result of changes in the parent chain. | By setting the WA_OpaquePaintEvent the widget is no longer transparent and no longer subject to updates as a result of changes in the parent chain. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
#include <stdio.h> | #include <stdio.h> | ||
class cDrawWindow : public QWidget | class cDrawWindow : public QWidget | ||
{ | { | ||
public: | public: | ||
cDrawWindow(QWidget *Parent) : QWidget(Parent) | cDrawWindow(QWidget *Parent) : QWidget(Parent) | ||
{ | { | ||
setAttribute(Qt::WA_OpaquePaintEvent); | setAttribute(Qt::WA_OpaquePaintEvent); | ||
} | } | ||
void paintEvent(QPaintEvent *pe) | void paintEvent(QPaintEvent *pe) | ||
Line 2,966: | Line 2,800: | ||
fprintf(stderr, "paintEvent "); | fprintf(stderr, "paintEvent "); | ||
} | } | ||
bool event(QEvent *e) | bool event(QEvent *e) | ||
{ | { | ||
switch (e->type()) | switch (e->type()) | ||
Line 2,975: | Line 2,809: | ||
} | } | ||
return QWidget::event(e); | return QWidget::event(e); | ||
} | } | ||
}; | }; | ||
class cMainWindow : public QMainWindow | class cMainWindow : public QMainWindow | ||
{ | { | ||
private: | private: | ||
cDrawWindow *w; | cDrawWindow *w; | ||
public: | public: | ||
cMainWindow(void) { | cMainWindow(void) { | ||
w = new cDrawWindow(this); | w = new cDrawWindow(this); | ||
setCentralWidget(w); | setCentralWidget(w); | ||
move(0, 0); } | move(0, 0); } | ||
}; | }; | ||
Line 2,993: | Line 2,827: | ||
QApplication a(argc, argv); | QApplication a(argc, argv); | ||
cMainWindow mw; | cMainWindow mw; | ||
mw.show(); | mw.show(); | ||
return a.exec(); | return a.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===I have problems building an application that uses a Qt Designer plugin on Windows. Can you give some advice?=== | ===I have problems building an application that uses a Qt Designer plugin on Windows. Can you give some advice?=== | ||
Line 3,003: | Line 2,837: | ||
plugin, e.g: | plugin, e.g: | ||
< | <syntaxhighlight lang="cpp"> | ||
class QDESIGNER_WIDGET_EXPORT button : public QPushButton | class QDESIGNER_WIDGET_EXPORT button : public QPushButton | ||
</ | </syntaxhighlight> | ||
Also, make sure you have the Q_OBJECT macro in your class declaration, if you | Also, make sure you have the Q_OBJECT macro in your class declaration, if you | ||
Line 3,014: | Line 2,848: | ||
In the .pro file of your plugin you also need to give some extra information | In the .pro file of your plugin you also need to give some extra information | ||
< | <syntaxhighlight> | ||
TEMPLATE = lib | TEMPLATE = lib | ||
</ | </syntaxhighlight> | ||
Make sure you specify the lib template since you are building a library. | Make sure you specify the lib template since you are building a library. | ||
< | <syntaxhighlight> | ||
DESTDIR = $$[QT_INSTALL_PLUGINS]/designer | DESTDIR = $$[QT_INSTALL_PLUGINS]/designer | ||
</ | </syntaxhighlight> | ||
In addition you need to specify where the plugin should be located. Qt will | In addition you need to specify where the plugin should be located. Qt will | ||
Line 3,029: | Line 2,863: | ||
An example .pro file may like look this: | An example .pro file may like look this: | ||
< | <syntaxhighlight> | ||
TEMPLATE = lib | TEMPLATE = lib | ||
CONFIG+= designer plugin debug_and_release | CONFIG+= designer plugin debug_and_release | ||
Line 3,038: | Line 2,872: | ||
DESTDIR = $$[QT_INSTALL_PLUGINS]/designer | DESTDIR = $$[QT_INSTALL_PLUGINS]/designer | ||
CONFIG += qt warn_on release plugin | CONFIG += qt warn_on release plugin | ||
</ | </syntaxhighlight> | ||
With your application you need to add the following to your application's .pro | With your application you need to add the following to your application's .pro | ||
file: | file: | ||
< | <syntaxhighlight> | ||
LIBS+=$$[QT_INSTALL_PLUGINS]/designer/nameOfYourPlugin.lib | LIBS+=$$[QT_INSTALL_PLUGINS]/designer/nameOfYourPlugin.lib | ||
</ | </syntaxhighlight> | ||
This line is necessary to link against the lib file and at runtime the | This line is necessary to link against the lib file and at runtime the | ||
Line 3,052: | Line 2,886: | ||
DESTDIR in the plugin's pro file. | DESTDIR in the plugin's pro file. | ||
< | <syntaxhighlight> | ||
INCLUDEPATH += text/example/yourPluginDir/yourWidget | INCLUDEPATH += text/example/yourPluginDir/yourWidget | ||
</ | </syntaxhighlight> | ||
You also need to specify the INCLUDEPATH, so that your application will be | You also need to specify the INCLUDEPATH, so that your application will be | ||
Line 3,061: | Line 2,895: | ||
An example .pro file can look as follows: | An example .pro file can look as follows: | ||
< | <syntaxhighlight> | ||
TEMPLATE = app | TEMPLATE = app | ||
LANGUAGE = C++ | LANGUAGE = C++ | ||
Line 3,069: | Line 2,903: | ||
SOURCES += main.cpp | SOURCES += main.cpp | ||
FORMS = form1.ui | FORMS = form1.ui | ||
</ | </syntaxhighlight> | ||
Finally, your application also needs to be able to find the plugin's dll. This | Finally, your application also needs to be able to find the plugin's dll. This | ||
Line 3,075: | Line 2,909: | ||
application, or by adding the path to the myPlugin.dll to the PATH environment | application, or by adding the path to the myPlugin.dll to the PATH environment | ||
variable. | variable. | ||
===How can I create checkable items in a QTreeWidget?=== | ===How can I create checkable items in a QTreeWidget?=== | ||
In order to create checkable items in a QTreeWidget http://doc.qt.io/qt-5 | In order to create checkable items in a QTreeWidget http://doc.qt.io/qt-5/qtreewidget.html, you need to pass in the Qt::ItemIsUserCheckable http://doc.qt.io/qt-5/qt.html#ItemFlag-enum flag to QTreeWidgetItem::setFlags() http://doc.qt.io/qt-5/qtreewidgetitem.html#setFlags in addition to calling QTreeWidgetItem::setCheckState() http://doc.qt.io/qt-5/qtreewidgetitem.html#setCheckState. See the following example for a demonstration: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
Line 3,094: | Line 2,928: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I avoid drawing the focus rect on my buttons?=== | ===How can I avoid drawing the focus rect on my buttons?=== | ||
In order to not draw the focus rect of the buttons it is necessary to subclass the style and reimplement QStyle::drawControl() http://doc.qt.io/qt-5/qstyle.html#drawControl to strip out the State_HasFocus http://doc.qt.io/qt-5 | In order to not draw the focus rect of the buttons it is necessary to subclass the style and reimplement QStyle::drawControl() http://doc.qt.io/qt-5/qstyle.html#drawControl to strip out the State_HasFocus http://doc.qt.io/qt-5/qstyle.html#StateFlag-enum state for the buttons. | ||
See the following example: | See the following example: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Style : public QWindowsStyle | class Style : public QWindowsStyle | ||
{ | { | ||
public: | public: | ||
Style() | Style() {} | ||
void drawControl(ControlElement element, const QStyleOption *option, | |||
void drawControl ( ControlElement element, const QStyleOption * option, | QPainter *painter, const QWidget *widget = nullptr) const | ||
{ | { | ||
if(element == CE_PushButton) { | if (element == QStyle::CE_PushButton) { | ||
const QStyleOptionButton *b = qstyleoption_cast<const QStyleOptionButton *>(option); | const QStyleOptionButton *b = qstyleoption_cast<const QStyleOptionButton *>(option); | ||
QStyleOptionButton *btn = (QStyleOptionButton *)b; | QStyleOptionButton *btn = (QStyleOptionButton *)b; | ||
Line 3,148: | Line 2,981: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===When the FileMode is DirectoryOnly in my QFileDialog, how can I select multiple directories?=== | ===When the FileMode is DirectoryOnly in my QFileDialog, how can I select multiple directories?=== | ||
By default it is only possible to select one directory when the FileMode http://doc.qt.io/qt-5 | By default it is only possible to select one directory when the FileMode http://doc.qt.io/qt-5/qfiledialog.html#FileMode-enum is DirectoryOnly. You can change this by getting hold of the QListView http://doc.qt.io/qt-5/qlistview.html and QTreeView http://doc.qt.io/qt-5/qtreeview.html children of the QFileDialog http://doc.qt.io/qt-5/qfiledialog.html and setting their selection mode to MultiSelection http://doc.qt.io/qt-5/qabstractitemview.html#SelectionMode-enum. | ||
See the following example: | See the following example: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
Line 3,171: | Line 3,004: | ||
t->setSelectionMode(QAbstractItemView::MultiSelection); | t->setSelectionMode(QAbstractItemView::MultiSelection); | ||
} | } | ||
w.exec(); | w.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===When converting my pixmap to a HBITMAP using toWinHBITMAP(QPixmap::PremultipliedAlpha ) , they appear with a black background. How can I give the icons a transparent background?=== | ===When converting my pixmap to a HBITMAP using toWinHBITMAP(QPixmap::PremultipliedAlpha ) , they appear with a black background. How can I give the icons a transparent background?=== | ||
Line 3,182: | Line 3,015: | ||
The following example demonstrates how this can be done: | The following example demonstrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
#include <qt_windows.h> | #include <qt_windows.h> | ||
Line 3,205: | Line 3,038: | ||
drawHBITMAP(dc, 100, 100, pix1.width(), pix1.height(), image1); | drawHBITMAP(dc, 100, 100, pix1.width(), pix1.height(), image1); | ||
} | } | ||
</ | </syntaxhighlight> | ||
Note that you need to link against msimg32.dll. | Note that you need to link against msimg32.dll. | ||
===How to compress data with Qt?=== | ===How to compress data with Qt?=== | ||
Qt uses the zlib library to provide compression. This means that you can compress and decompress your bytearrays of data using Qt. See the documentation on qUncompress() http://doc.qt.io/qt-5/qbytearray.html#qUncompress | Qt uses the zlib library to provide compression. This means that you can compress and decompress your bytearrays of data using Qt. See the documentation on qUncompress() http://doc.qt.io/qt-5/qbytearray.html#qUncompress | ||
Note that this does not produce file archives that can be opened by other applications, to do that you will need to write it yourself using Qt's custom file handling system http://doc.qt.io/qt- | Note that this does not produce file archives that can be opened by other applications, to do that you will need to write it yourself using Qt's custom file handling system http://doc.qt.io/qt-4.8/qabstractfileengine.html#details or use a 3rd party library. | ||
===How can I prevent the MDI subwindows from closing when pressing Ctrl+W?=== | ===How can I prevent the MDI subwindows from closing when pressing Ctrl+W?=== | ||
You can stop the Ctrl+W shortcut from triggering by reimplementing the eventFilter() http://doc.qt.io/qt-5/qobject.html#eventFilter for your QMainWindow http://doc.qt.io/qt-5 | You can stop the Ctrl+W shortcut from triggering by reimplementing the eventFilter() http://doc.qt.io/qt-5/qobject.html#eventFilter for your QMainWindow http://doc.qt.io/qt-5/qmainwindow.html and returning true when the shortcut is Ctrl+W. | ||
The event filter can be installed on the subwindows or on the application itself. Note that installing the event filter on the application will require more resources. | The event filter can be installed on the subwindows or on the application itself. Note that installing the event filter on the application will require more resources. | ||
The example below illustrates how this can be done: | The example below illustrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Object : public QObject | class Object : public QObject | ||
Line 3,261: | Line 3,093: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Compiling a Qt program fails with error messages looking something like this: undefined reference to `_vt.11QPushButton'=== | ===Compiling a Qt program fails with error messages looking something like this: undefined reference to `_vt.11QPushButton'=== | ||
Line 3,276: | Line 3,108: | ||
means that the program has been compiled with a version of Qt that is newer | means that the program has been compiled with a version of Qt that is newer | ||
than the one on your system. Upgrade to the latest version of Qt. | than the one on your system. Upgrade to the latest version of Qt. | ||
===Polling SQL connection to test connectivity.=== | ===Polling SQL connection to test connectivity.=== | ||
Line 3,284: | Line 3,116: | ||
There isn't actually a signal or any other indicator to poll the status of a connection in this case. The workaround for this is to send a query that you know will always be returned true, and if it returns false, you will know that the connection is down. | There isn't actually a signal or any other indicator to poll the status of a connection in this case. The workaround for this is to send a query that you know will always be returned true, and if it returns false, you will know that the connection is down. | ||
===QWebView does not display Chinese fonts from a Chinese web site=== | ===QWebView does not display Chinese fonts from a Chinese web site=== | ||
On X11 this problem can be solved by installing libFreetype and libFontconfig. These libraries are needed to render the true type fonts that contain these characters. On Windows you need to install the Chinese fonts from the Windows installation CD to get this to work. | On X11 this problem can be solved by installing libFreetype and libFontconfig. These libraries are needed to render the true type fonts that contain these characters. On Windows you need to install the Chinese fonts from the Windows installation CD to get this to work. | ||
===How can I use QSound with ALSA ?=== | ===How can I use QSound with ALSA ?=== | ||
There is no ALSA support for QSound as ALSA only works in Linux. Qt uses its own sound server(QSS) that interacts with /dev/dsp directly. If you want to use ALSA on Linux, then implement it directly with the ALSA API or use Phonon. | There is no ALSA support for QSound as ALSA only works in Linux. Qt uses its own sound server(QSS) that interacts with /dev/dsp directly. If you want to use ALSA on Linux, then implement it directly with the ALSA API or use Phonon. | ||
===Is there a Qt way to handle UNIX/POSIX signals?=== | ===Is there a Qt way to handle UNIX/POSIX signals?=== | ||
Line 3,298: | Line 3,130: | ||
http://doc.qt.io/qt-5/unix-signals.html | http://doc.qt.io/qt-5/unix-signals.html | ||
===How can I move a window around when using Qt::FramelessWindowHint?=== | ===How can I move a window around when using Qt::FramelessWindowHint?=== | ||
You need to reimplement the mouse event handlers for the widgets you would like be able to move your window with. Here is an example using QMenuBar http://doc.qt.io/qt-5 | You need to reimplement the mouse event handlers for the widgets you would like be able to move your window with. Here is an example using QMenuBar http://doc.qt.io/qt-5/qmenubar.html: | ||
< | <syntaxhighlight lang="cpp"> | ||
#ifndef CMENUBAR_H | #ifndef CMENUBAR_H | ||
#define CMENUBAR_H | #define CMENUBAR_H | ||
Line 3,370: | Line 3,202: | ||
} | } | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Antialiasing does not work with VNC=== | ===Antialiasing does not work with VNC=== | ||
This is most likely due to lack of XRender support in the VNC Client. To get antialiasing to work you must either enable XRender support on the VNC Client, or use the raster paint engine. This can be done by starting the application with ./myApp -graphicssystem raster | This is most likely due to lack of XRender support in the VNC Client. To get antialiasing to work you must either enable XRender support on the VNC Client, or use the raster paint engine. This can be done by starting the application with ./myApp -graphicssystem raster | ||
===On which operating systems does Qt Creator run?=== | ===On which operating systems does Qt Creator run?=== | ||
Line 3,380: | Line 3,212: | ||
Supported platforms http://doc.qt.io/qt-5/qtcreator-2.1/creator-os-supported-platforms.html | Supported platforms http://doc.qt.io/qt-5/qtcreator-2.1/creator-os-supported-platforms.html | ||
===What is the difference between a static and a shared build of the Qt library?=== | ===What is the difference between a static and a shared build of the Qt library?=== | ||
Line 3,388: | Line 3,220: | ||
with a static library will be at least 1.5MB in size and it is not possible to | with a static library will be at least 1.5MB in size and it is not possible to | ||
build or use any components or plugins with a static Qt library. | build or use any components or plugins with a static Qt library. | ||
===Moving my application away from MFC, why would I select Qt as the toolkit to move to?=== | ===Moving my application away from MFC, why would I select Qt as the toolkit to move to?=== | ||
Line 3,406: | Line 3,238: | ||
* Qt provides a consistent class API that covers both GUI and all the operating system functionality needed by most applications. | * Qt provides a consistent class API that covers both GUI and all the operating system functionality needed by most applications. | ||
===How can I prevent the clicked() signal from being emitted when I want to grab the doubleClicked() signal in my item view ?=== | ===How can I prevent the clicked() signal from being emitted when I want to grab the doubleClicked() signal in my item view ?=== | ||
Normally the clicked() signal will be emitted in addition to the doubleClicked() signal since you are actually clicking on the widget. The same happens with events when you double click on a widget, you get a press event, release event then a double click event. The press followed by the release indicates that a click occurred. If you don't want this behavior then you can start a timer in the mouseReleaseEvent() http://doc.qt.io/qt-5 | Normally the clicked() signal will be emitted in addition to the doubleClicked() signal since you are actually clicking on the widget. The same happens with events when you double click on a widget, you get a press event, release event then a double click event. The press followed by the release indicates that a click occurred. If you don't want this behavior then you can start a timer in the mouseReleaseEvent() http://doc.qt.io/qt-5/qabstractitemview.html#mouseReleaseEvent and then in the mouseDoubleClickEvent() http://doc.qt.io/qt-5/qabstractitemview.html#mouseDoubleClickEvent kill the timer. If the timer times out, you can emit the clicked signal and stop the timer. | ||
See the following example for an illustration: | See the following example for an illustration: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class TableWidget : public QTableWidget | class TableWidget : public QTableWidget | ||
Line 3,422: | Line 3,254: | ||
TableWidget() | TableWidget() | ||
{ | { | ||
ignoreNextRelease = false; | ignoreNextRelease = false; | ||
timer = new QTimer(this); | timer = new QTimer(this); | ||
setColumnCount(3); | setColumnCount(3); | ||
Line 3,430: | Line 3,262: | ||
connect(timer, SIGNAL(timeout()), this, SLOT(emitClicked())); | connect(timer, SIGNAL(timeout()), this, SLOT(emitClicked())); | ||
} | } | ||
void mouseReleaseEvent(QMouseEvent *event) | void mouseReleaseEvent(QMouseEvent *event) | ||
{ | { | ||
Line 3,441: | Line 3,273: | ||
ignoreNextRelease = false; | ignoreNextRelease = false; | ||
} | } | ||
void mouseDoubleClickEvent(QMouseEvent *event) | void mouseDoubleClickEvent(QMouseEvent *event) | ||
{ | { | ||
Line 3,450: | Line 3,282: | ||
public slots: | public slots: | ||
void testSlot() | void testSlot() | ||
{ | { | ||
qDebug("cellClicked() was emitted"); | qDebug("cellClicked() was emitted"); | ||
} | } | ||
void testSlot2() | void testSlot2() | ||
{ | { | ||
qDebug("cellDoubleClicked was emitted"); | qDebug("cellDoubleClicked was emitted"); | ||
} | } | ||
void emitClicked() | void emitClicked() | ||
{ | { | ||
Line 3,466: | Line 3,298: | ||
timer->stop(); | timer->stop(); | ||
} | } | ||
private: | private: | ||
QTimer *timer; | QTimer *timer; | ||
bool ignoreNextRelease; | bool ignoreNextRelease; | ||
}; | }; | ||
Line 3,478: | Line 3,310: | ||
TableWidget box; | TableWidget box; | ||
box.show(); | box.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I draw custom subcontrols for a complex control ?=== | ===How can I draw custom subcontrols for a complex control ?=== | ||
You can achieve this either by subclassing the style or by using a stylesheet http://doc.qt.io/qt-5/stylesheet.html. If you want to style the drop-down button of a combobox for example, then you can subclass the style and reimplement drawComplexControl() http://doc.qt.io/qt-5/qstyle.html#drawComplexControl to remove the existing button. Then after the style has done its painting, you can do your custom painting. See the following example: | You can achieve this either by subclassing the style or by using a stylesheet http://doc.qt.io/qt-5/stylesheet.html. If you want to style the drop-down button of a combobox for example, then you can subclass the style and reimplement drawComplexControl() http://doc.qt.io/qt-5/qstyle.html#drawComplexControl to remove the existing button. Then after the style has done its painting, you can do your custom painting. See the following example: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Style : public QWindowsStyle | class Style : public QWindowsStyle | ||
Line 3,493: | Line 3,325: | ||
public: | public: | ||
Style() {} | Style() {} | ||
void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = | void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = nullptr) const override | ||
{ | |||
if (const QStyleOptionComboBox *group = qstyleoption_cast<const QStyleOptionComboBox*>(option)) { | if (const QStyleOptionComboBox *group = qstyleoption_cast<const QStyleOptionComboBox*>(option)) { | ||
QStyleOptionComboBox newComboBox(*group); | QStyleOptionComboBox newComboBox(*group); | ||
Line 3,523: | Line 3,356: | ||
} | } | ||
</ | </syntaxhighlight> | ||
Other parts of the combobox can be modified by accessing the properties of the | Other parts of the combobox can be modified by accessing the properties of the | ||
QStyleOptionComplex pointer passed in to drawComplexControl in the example | QStyleOptionComplex pointer passed in to drawComplexControl in the example | ||
Line 3,536: | Line 3,369: | ||
To see how this works, you can run the stylesheet example under yourQtVersion\examples\widgets\stylesheet and open the editor under File/Edit Style to | To see how this works, you can run the stylesheet example under yourQtVersion\examples\widgets\stylesheet and open the editor under File/Edit Style to | ||
see how the combobox is styled there. | see how the combobox is styled there. | ||
===How can I change the header text of my model based view?=== | ===How can I change the header text of my model based view?=== | ||
In order to change the header text of a model based view you need to reimplement headerData() http://doc.qt.io/qt-5/qabstractitemmodel.html#headerData and return the text you want for the relevant section, orientation and row there. | In order to change the header text of a model based view you need to reimplement headerData() http://doc.qt.io/qt-5/qabstractitemmodel.html#headerData and return the text you want for the relevant section, orientation and row there. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Model : public QAbstractTableModel { | class Model : public QAbstractTableModel { | ||
Line 3,612: | Line 3,445: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I create a dialog that can be closed programatically, but not by the user ?=== | ===How can I create a dialog that can be closed programatically, but not by the user ?=== | ||
You can achieve this by reimplementing closeEvent() http://doc.qt.io/qt-5/qwidget.html#closeEvent and then ignoring or accepting the event depending on a flag. | You can achieve this by reimplementing closeEvent() http://doc.qt.io/qt-5/qwidget.html#closeEvent and then ignoring or accepting the event depending on a flag. | ||
The following is an example of how to do this: | The following is an example of how to do this: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Dialog : public QDialog | class Dialog : public QDialog | ||
Line 3,662: | Line 3,495: | ||
dialog.show(); | dialog.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Is it possible for either the left or right dock areas to have full height of their side rather than having the bottom take the full width?=== | ===Is it possible for either the left or right dock areas to have full height of their side rather than having the bottom take the full width?=== | ||
It is possible to get what you are looking for, but you have to be kind of sneaky about it. The real trick is to have a QMainWindow http://doc.qt.io/qt-5 | It is possible to get what you are looking for, but you have to be kind of sneaky about it. The real trick is to have a QMainWindow http://doc.qt.io/qt-5/qmainwindow.html as the central widget of your QMainWindow and then dock bottom QDockWidget http://doc.qt.io/qt-5/qdockwidget.html in there. Then you can disable the the bottom dock area for your toplevel QMainWindow and dock the left and right dock windows there. We do this trick with Linguist to get a very similar look, so you can check out Linguist http://doc.qt.io/qt-5/linguist-manual.html to see how it works there. | ||
The example below is a demonstration of how this can be done. | The example below is a demonstration of how this can be done. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class MainWindow : public QMainWindow | class MainWindow : public QMainWindow | ||
Line 3,677: | Line 3,510: | ||
public: | public: | ||
MainWindow(QWidget *parent = | MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) | ||
{ | { | ||
QMainWindow *window = new QMainWindow(this); | QMainWindow *window = new QMainWindow(this); | ||
Line 3,702: | Line 3,535: | ||
return a.exec(); | return a.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===QScriptEngine::uncaughtExceptionNumber() is returning 0 even though the error is elsewhere. What's wrong?=== | ===QScriptEngine::uncaughtExceptionNumber() is returning 0 even though the error is elsewhere. What's wrong?=== | ||
The cause of the problem probably is QScriptValue::toString() http://doc.qt.io/qt-5 | The cause of the problem probably is QScriptValue::toString() http://doc.qt.io/qt-5/qscriptvalue.html#toString is being called on the QScriptValue returned from the evaluate() http://doc.qt.io/qt-5/qscriptengine.html#evaluate call before uncaughtExceptionNumber() is called. When QScriptValue::toString() http://doc.qt.io/qt-5/qscriptvalue.html#toString is called it will reset the exception number in the QScriptEngine http://doc.qt.io/qt-5/qscriptengine.html since it is ready for a new evaluate(). So code like: | ||
< | <syntaxhighlight lang="cpp"> | ||
QScriptValue val = engine->evaluate(code); | QScriptValue val = engine->evaluate(code); | ||
if (val.isError()) { | if (val.isError()) { | ||
Line 3,715: | Line 3,548: | ||
} | } | ||
</ | </syntaxhighlight> | ||
Should be changed to: | Should be changed to: | ||
< | <syntaxhighlight lang="cpp"> | ||
QScriptValue val = engine->evaluate(code); | QScriptValue val = engine->evaluate(code); | ||
if (val.isError()) { | if (val.isError()) { | ||
Line 3,725: | Line 3,558: | ||
} | } | ||
</ | </syntaxhighlight> | ||
So that the uncaughtExceptionNumber() is obtained before toString() is called. | So that the uncaughtExceptionNumber() is obtained before toString() is called. | ||
===I use a Qt-plugin in a non-Qt program on the Mac. When unloading the plugin, the application's menubar is deleted. What's going wrong ?=== | ===I use a Qt-plugin in a non-Qt program on the Mac. When unloading the plugin, the application's menubar is deleted. What's going wrong ?=== | ||
Line 3,733: | Line 3,566: | ||
In general, most plugins in a non-Qt application don't need to interact with the menubar anyway. | In general, most plugins in a non-Qt application don't need to interact with the menubar anyway. | ||
===Is Qt compatible with .NET?=== | ===Is Qt compatible with .NET?=== | ||
Yes. You can use Qt to create .NET-compatible applications. For details on how to do this, please refer to Using Qt objects in Microsoft .NET in the documentation http://doc.qt.io/qt-5/activeqt.html. | Yes. You can use Qt to create .NET-compatible applications. For details on how to do this, please refer to Using Qt objects in Microsoft .NET in the documentation http://doc.qt.io/qt-5/activeqt.html. | ||
===Does Qt Creator support embedded/mobile software development?=== | ===Does Qt Creator support embedded/mobile software development?=== | ||
Yes, Qt Creator can be used for developing for any platform that is supported by Qt. | Yes, Qt Creator can be used for developing for any platform that is supported by Qt. | ||
===Which image formats does Qt support?=== | ===Which image formats does Qt support?=== | ||
Line 3,790: | Line 3,623: | ||
See http://doc.qt.io/qt-5/stylesheet.html for more information | See http://doc.qt.io/qt-5/stylesheet.html for more information | ||
===How can I change the size of the icon in the tab of a QToolBox?=== | ===How can I change the size of the icon in the tab of a QToolBox?=== | ||
The easiest way is probably by setting a stylesheet http://doc.qt.io/qt-5 | The easiest way is probably by setting a stylesheet http://doc.qt.io/qt-5/stylesheet.html on the QToolBox as follows: | ||
< | <syntaxhighlight lang="cpp"> | ||
toolbox.setStyleSheet("icon-size: aNumberpx"); | toolbox.setStyleSheet("icon-size: aNumberpx"); | ||
</ | </syntaxhighlight> | ||
You can also achieve it by subclassing the style and setting the value of pixelMetric() http://doc.qt.io/qt-5 | You can also achieve it by subclassing the style and setting the value of pixelMetric() http://doc.qt.io/qt-5/qstyle.html#pixelMetric to what you want when the metric is QStyle::PM_SmallIconSize and the widget inherits QToolBox. The example below illustrates both ways. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Style : public QWindowsStyle | class Style : public QWindowsStyle | ||
{ | { | ||
public: | public: | ||
Style() | Style() {} | ||
int pixelMetric (PixelMetric metric, const QStyleOption * option = nullptr, const QWidget * widget = nullptr) const override | |||
int pixelMetric ( PixelMetric metric, const QStyleOption * option = | |||
{ | { | ||
if (metric == QStyle::PM_SmallIconSize && widget->inherits("QToolBox")) { | if (metric == QStyle::PM_SmallIconSize && widget->inherits("QToolBox")) { | ||
return 50; | return 50; | ||
} | |||
return QWindowsStyle::pixelMetric(metric, option, widget); | return QWindowsStyle::pixelMetric(metric, option, widget); | ||
} | } | ||
Line 3,825: | Line 3,656: | ||
QPixmap pix(50, 50); | QPixmap pix(50, 50); | ||
pix.fill(Qt::red); | pix.fill(Qt::red); | ||
addItem(new QLineEdit(this), QIcon(pix), "QLineEdit"); | addItem(new QLineEdit(this), QIcon(pix), "QLineEdit"); | ||
addItem(new QPushButton("Click me", this), "QPushButton"); | addItem(new QPushButton("Click me", this), "QPushButton"); | ||
Line 3,841: | Line 3,672: | ||
#endif | #endif | ||
box.show(); | box.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Is there a way to tell QTreeView to always resize itself based on the contents of all columns?=== | ===Is there a way to tell QTreeView to always resize itself based on the contents of all columns?=== | ||
To make a QTreeView always resize itself based on the contents of all columns, you can connect to the dataChanged() http://doc.qt.io/qt-5 | To make a QTreeView always resize itself based on the contents of all columns, you can connect to the dataChanged() http://doc.qt.io/qt-5/qabstractitemmodel.html#dataChanged signal and call resizeColumnToContents() http://doc.qt.io/qt-5/qtreeview.html#resizeColumnToContents when the data changes. | ||
See the following example for an illustration: | See the following example for an illustration: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class TreeView :public QTreeView | class TreeView :public QTreeView | ||
Line 3,859: | Line 3,690: | ||
TreeView(); | TreeView(); | ||
public slots: | public slots: | ||
void adaptColumns(const QModelIndex &topleft, | void adaptColumns(const QModelIndex &topleft, | ||
const QModelIndex &bottomRight); | const QModelIndex &bottomRight); | ||
private: | private: | ||
Line 3,882: | Line 3,713: | ||
} | } | ||
setModel(model); | setModel(model); | ||
connect(model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex& ) ), | connect(model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex& ) ), | ||
this, SLOT(adaptColumns(const QModelIndex &, const QModelIndex&) ) ); | this, SLOT(adaptColumns(const QModelIndex &, const QModelIndex&) ) ); | ||
} | } | ||
Line 3,906: | Line 3,737: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I make the scrollbar thinner ?=== | ===How can I make the scrollbar thinner ?=== | ||
The scrollbar will not be thinner than the QApplication::globalStrut() http://doc.qt.io/qt-5 | The scrollbar will not be thinner than the QApplication::globalStrut() http://doc.qt.io/qt-5/qapplication.html#globalStrut-prop so you can use this to make sure it has a certain minimum size. | ||
Another approach that also can make it thinner than the default is to subclass the style and reimplement pixelMetric() http://doc.qt.io/qt-5 | Another approach that also can make it thinner than the default is to subclass the style and reimplement pixelMetric() http://doc.qt.io/qt-5/qstyle.html#pixelMetric | ||
< | <syntaxhighlight lang="cpp"> | ||
int pixelMetric(PixelMetric metric, const QWidget *widget = | int pixelMetric(PixelMetric metric, const QWidget *widget = nullptr) const | ||
{ | { | ||
if (metric == QStyle::PM_ScrollBarExtent) | if (metric == QStyle::PM_ScrollBarExtent) | ||
Line 3,920: | Line 3,751: | ||
return style->pixelMetric(metric, widget); | return style->pixelMetric(metric, widget); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I detect a period of no user interaction?=== | ===How can I detect a period of no user interaction?=== | ||
What you will need to do is use a QTimer http://doc.qt.io/qt-5 | What you will need to do is use a QTimer http://doc.qt.io/qt-5/qtimer.html that times out after a number of minutes of no user interaction. Whenever there is user interaction, then you restart the timer. The easiest way to detect any user interaction within an application i.e. mouse clicks(any button), mouse wheel and keystrokes is to install an event filter on the application that listens for these kind of events. For example: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Widget : public QWidget | class Widget : public QWidget | ||
Line 3,950: | Line 3,781: | ||
timer->start(6000); | timer->start(6000); | ||
break; | break; | ||
default: | default: | ||
break; | break; | ||
} | } | ||
Line 3,973: | Line 3,804: | ||
box.resize(100, 200); | box.resize(100, 200); | ||
box.show(); | box.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I change the color of the items in my model?=== | ===How can I change the color of the items in my model?=== | ||
In order to change the color of the items in the model you need to reimplement the data() http://doc.qt.io/qt-5/qabstractitemmodel.html#data function and return the colors you want for the Qt::BackgroundColorRole or the Qt::TextColorRole roles http://doc.qt.io/qt-5/qt.html#ItemDataRole-enum. | In order to change the color of the items in the model you need to reimplement the data() http://doc.qt.io/qt-5/qabstractitemmodel.html#data function and return the colors you want for the Qt::BackgroundColorRole or the Qt::TextColorRole roles http://doc.qt.io/qt-5/qt.html#ItemDataRole-enum. | ||
The example below illustrates how this can be achieved. | The example below illustrates how this can be achieved. | ||
Note that you can also reimplement QStyledItemDelegate::paint() http://doc.qt.io/qt-5 | Note that you can also reimplement QStyledItemDelegate::paint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#paint in order to change the color the items in a view. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class ColorModel : public QAbstractTableModel | class ColorModel : public QAbstractTableModel | ||
{ | { | ||
public: | public: | ||
ColorModel(QObject *parent) : QAbstractTableModel(parent) | ColorModel(QObject *parent) : QAbstractTableModel(parent) | ||
{ | { | ||
QStringList firstRow; | QStringList firstRow; | ||
QStringList secondRow; | QStringList secondRow; | ||
for (int i = 0; i < 5; i++ ) { | for (int i = 0; i < 5; i++ ) { | ||
firstRow.insert(i,"Row " + QString::number(i+1)); | firstRow.insert(i,"Row " + QString::number(i+1)); | ||
secondRow.insert(i,"Row " + QString::number(i+1)); | secondRow.insert(i,"Row " + QString::number(i+1)); | ||
} | } | ||
stringList << firstRow << secondRow; | stringList << firstRow << secondRow; | ||
} | } | ||
// Returns the number of rows | // Returns the number of rows | ||
int rowCount(const QModelIndex &parent = QModelIndex()) const | int rowCount(const QModelIndex &parent = QModelIndex()) const | ||
{ | { | ||
return 2; | return 2; | ||
} | } | ||
// Returns the number of columns | // Returns the number of columns | ||
int columnCount(const QModelIndex &parent = QModelIndex()) const | int columnCount(const QModelIndex &parent = QModelIndex()) const | ||
{ | { | ||
return 5; | return 5; | ||
} | } | ||
// Returns an appropriate value for the requested data. | // Returns an appropriate value for the requested data. | ||
// If the view requests an invalid index or if the role is not | // If the view requests an invalid index or if the role is not | ||
// Qt::DisplayRole, Qt::BackgroundColorRole or QTextColorRole, an invalid variant is | // Qt::DisplayRole, Qt::BackgroundColorRole or QTextColorRole, an invalid variant is | ||
// returned. | // returned. | ||
// Any valid index that corresponds to a string for the index's column and row in | // Any valid index that corresponds to a string for the index's column and row in | ||
// the stringlist is returned for the Qt::DisplayRole | // the stringlist is returned for the Qt::DisplayRole | ||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const | QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const | ||
{ | { | ||
if (!index.isValid()) | if (!index.isValid()) | ||
return QVariant(); | return QVariant(); | ||
if (role == Qt::BackgroundRole) | if (role == Qt::BackgroundRole) | ||
{ | { | ||
if (index.row() == 0) | if (index.row() == 0) | ||
return QColor(Qt::blue); | return QColor(Qt::blue); | ||
else | else | ||
return QColor(Qt::white); | return QColor(Qt::white); | ||
} else if (role == Qt::DisplayRole) { | } else if (role == Qt::DisplayRole) { | ||
QStringList list = (QStringList)stringList.at(index.row()); | QStringList list = (QStringList)stringList.at(index.row()); | ||
return list.at(index.column()); | return list.at(index.column()); | ||
} else if (role == Qt::ForegroundRole ) { | } else if (role == Qt::ForegroundRole ) { | ||
if (index.row() == 1) | if (index.row() == 1) | ||
return QColor(Qt::red); | return QColor(Qt::red); | ||
} | } | ||
return QVariant(); | return QVariant(); | ||
} | } | ||
private: | private: | ||
// Each row will consist of a list of strings | // Each row will consist of a list of strings | ||
QList<QStringList>stringList; | QList<QStringList>stringList; | ||
}; | }; | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
QWidget widget; | QWidget widget; | ||
QHBoxLayout *layout = new QHBoxLayout(&widget); | QHBoxLayout *layout = new QHBoxLayout(&widget); | ||
QTreeView *treeView = new QTreeView(&widget); | QTreeView *treeView = new QTreeView(&widget); | ||
QTableView *tableView = new QTableView(&widget); | QTableView *tableView = new QTableView(&widget); | ||
ColorModel *model = new ColorModel(tableView); | ColorModel *model = new ColorModel(tableView); | ||
tableView->setModel(model); | tableView->setModel(model); | ||
treeView->setModel(model); | treeView->setModel(model); | ||
layout->addWidget(treeView); | layout->addWidget(treeView); | ||
layout->addWidget(tableView); | layout->addWidget(tableView); | ||
widget.show(); | widget.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I handle events in the titlebar and change its color etc ?=== | ===How can I handle events in the titlebar and change its color etc ?=== | ||
The titlebar belongs to the OS and we don't have control over that one. You can create your own titlebar, but note that this requires some work. In order to create your own titlebar then make a QWidget http://doc.qt.io/qt-5 | The titlebar belongs to the OS and we don't have control over that one. You can create your own titlebar, but note that this requires some work. In order to create your own titlebar then make a QWidget http://doc.qt.io/qt-5/qwidget.html subclass that contains three toolbuttons that handle the close, minimize and maximize events in addition to the moving of the window. | ||
Then make a QFrame http://doc.qt.io/qt-5 | Then make a QFrame http://doc.qt.io/qt-5/qframe.html subclass which does not have a titlebar provided via the window system. This is done by setting the Qt::FramelessWindowHint http://doc.qt.io/qt-5/qt.html#WindowType-enum window flag, however this will make it impossible to resize or move the window via the window system. What can be done is you can add your custom titlbar as a private member to the frame and add the it first to the frame's vertical layout. The frame also needs a content widget which allows widgets to be added to it. Finally the QFrame subclass needs to reimplement the mouse events to handle the resizing and moving of the window. | ||
The example below demonstrates how this can be achieved. | The example below demonstrates how this can be achieved. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class TitleBar : public QWidget | class TitleBar : public QWidget | ||
Line 4,079: | Line 3,910: | ||
// Don't let this widget inherit the parent's backround color | // Don't let this widget inherit the parent's backround color | ||
setAutoFillBackground(true); | setAutoFillBackground(true); | ||
// Use a brush with a Highlight color role to render the background | // Use a brush with a Highlight color role to render the background | ||
setBackgroundRole(QPalette::Highlight); | setBackgroundRole(QPalette::Highlight); | ||
minimize = new QToolButton(this); | minimize = new QToolButton(this); | ||
maximize = new QToolButton(this); | maximize = new QToolButton(this); | ||
close= new QToolButton(this); | close= new QToolButton(this); | ||
// Use the style to set the button pixmaps | // Use the style to set the button pixmaps | ||
QPixmap pix = style()->standardPixmap(QStyle::SP_TitleBarCloseButton); | QPixmap pix = style()->standardPixmap(QStyle::SP_TitleBarCloseButton); | ||
close->setIcon(pix); | close->setIcon(pix); | ||
maxPix = style()->standardPixmap(QStyle::SP_TitleBarMaxButton); | maxPix = style()->standardPixmap(QStyle::SP_TitleBarMaxButton); | ||
maximize->setIcon(maxPix); | maximize->setIcon(maxPix); | ||
pix = style()->standardPixmap(QStyle::SP_TitleBarMinButton); | pix = style()->standardPixmap(QStyle::SP_TitleBarMinButton); | ||
minimize->setIcon(pix); | minimize->setIcon(pix); | ||
restorePix = style()->standardPixmap(QStyle::SP_TitleBarNormalButton); | restorePix = style()->standardPixmap(QStyle::SP_TitleBarNormalButton); | ||
minimize->setMinimumHeight(20); | minimize->setMinimumHeight(20); | ||
close->setMinimumHeight(20); | close->setMinimumHeight(20); | ||
maximize->setMinimumHeight(20); | maximize->setMinimumHeight(20); | ||
QLabel *label = new QLabel(this); | QLabel *label = new QLabel(this); | ||
label->setText("Window Title"); | label->setText("Window Title"); | ||
parent->setWindowTitle("Window Title"); | parent->setWindowTitle("Window Title"); | ||
QHBoxLayout *hbox = new QHBoxLayout(this); | QHBoxLayout *hbox = new QHBoxLayout(this); | ||
hbox->addWidget(label); | hbox->addWidget(label); | ||
hbox->addWidget(minimize); | hbox->addWidget(minimize); | ||
hbox->addWidget(maximize); | hbox->addWidget(maximize); | ||
hbox->addWidget(close); | hbox->addWidget(close); | ||
hbox->insertStretch(1, 500); | hbox->insertStretch(1, 500); | ||
hbox->setSpacing(0); | hbox->setSpacing(0); | ||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); | setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); | ||
maxNormal = false; | maxNormal = false; | ||
connect(close, SIGNAL( clicked() ), parent, SLOT(close() ) ); | connect(close, SIGNAL( clicked() ), parent, SLOT(close() ) ); | ||
connect(minimize, SIGNAL( clicked() ), this, SLOT(showSmall() ) ); | connect(minimize, SIGNAL( clicked() ), this, SLOT(showSmall() ) ); | ||
connect(maximize, SIGNAL( clicked() ), this, SLOT(showMaxRestore() ) ); | connect(maximize, SIGNAL( clicked() ), this, SLOT(showMaxRestore() ) ); | ||
} | } | ||
public slots: | public slots: | ||
void showSmall() | void showSmall() | ||
Line 4,130: | Line 3,961: | ||
parentWidget()->showMinimized(); | parentWidget()->showMinimized(); | ||
} | } | ||
void showMaxRestore() | void showMaxRestore() | ||
{ | { | ||
Line 4,169: | Line 4,000: | ||
{ | { | ||
public: | public: | ||
Frame() | Frame() | ||
{ | { | ||
m_mouse_down = false; | m_mouse_down = false; | ||
setFrameShape(Panel); | setFrameShape(Panel); | ||
// Make this a borderless window which can't | // Make this a borderless window which can't | ||
// be resized or moved via the window system | // be resized or moved via the window system | ||
setWindowFlags(Qt::FramelessWindowHint); | setWindowFlags(Qt::FramelessWindowHint); | ||
setMouseTracking(true); | setMouseTracking(true); | ||
m_titleBar = new TitleBar(this); | m_titleBar = new TitleBar(this); | ||
m_content = new QWidget(this); | m_content = new QWidget(this); | ||
QVBoxLayout *vbox = new QVBoxLayout(this); | QVBoxLayout *vbox = new QVBoxLayout(this); | ||
vbox->addWidget(m_titleBar); | vbox->addWidget(m_titleBar); | ||
vbox->setMargin(0); | vbox->setMargin(0); | ||
vbox->setSpacing(0); | vbox->setSpacing(0); | ||
QVBoxLayout *layout = new QVBoxLayout(this); | QVBoxLayout *layout = new QVBoxLayout(this); | ||
layout->addWidget(m_content); | layout->addWidget(m_content); | ||
Line 4,195: | Line 4,026: | ||
vbox->addLayout(layout); | vbox->addLayout(layout); | ||
} | } | ||
// Allows you to access the content area of the frame | // Allows you to access the content area of the frame | ||
// where widgets and layouts can be added | // where widgets and layouts can be added | ||
QWidget *contentWidget() const { return m_content; } | QWidget *contentWidget() const { return m_content; } | ||
TitleBar *titleBar() const { return m_titleBar; } | TitleBar *titleBar() const { return m_titleBar; } | ||
void mousePressEvent(QMouseEvent *e) | void mousePressEvent(QMouseEvent *e) | ||
{ | { | ||
Line 4,207: | Line 4,038: | ||
m_mouse_down = e->button() == Qt::LeftButton; | m_mouse_down = e->button() == Qt::LeftButton; | ||
} | } | ||
void mouseMoveEvent(QMouseEvent *e) | void mouseMoveEvent(QMouseEvent *e) | ||
{ | { | ||
int x = e->x(); | int x = e->x(); | ||
int y = e->y(); | int y = e->y(); | ||
if (m_mouse_down) { | if (m_mouse_down) { | ||
int dx = x - m_old_pos.x(); | int dx = x - m_old_pos.x(); | ||
int dy = y - m_old_pos.y(); | int dy = y - m_old_pos.y(); | ||
QRect g = geometry(); | QRect g = geometry(); | ||
if (left) | if (left) | ||
g.setLeft(g.left() + dx); | g.setLeft(g.left() + dx); | ||
Line 4,225: | Line 4,056: | ||
if (bottom) | if (bottom) | ||
g.setBottom(g.bottom() + dy); | g.setBottom(g.bottom() + dy); | ||
setGeometry(g); | setGeometry(g); | ||
m_old_pos = QPoint(!left ? e->x() : m_old_pos.x(), e->y()); | m_old_pos = QPoint(!left ? e->x() : m_old_pos.x(), e->y()); | ||
} else { | } else { | ||
Line 4,235: | Line 4,066: | ||
bottom = qAbs(y - r.bottom()) <= 5; | bottom = qAbs(y - r.bottom()) <= 5; | ||
bool hor = left | right; | bool hor = left | right; | ||
if (hor && bottom) { | if (hor && bottom) { | ||
if (left) | if (left) | ||
setCursor(Qt::SizeBDiagCursor); | setCursor(Qt::SizeBDiagCursor); | ||
else | else | ||
setCursor(Qt::SizeFDiagCursor); | setCursor(Qt::SizeFDiagCursor); | ||
} else if (hor) { | } else if (hor) { | ||
Line 4,250: | Line 4,081: | ||
} | } | ||
} | } | ||
void mouseReleaseEvent(QMouseEvent *e) | void mouseReleaseEvent(QMouseEvent *e) | ||
{ | { | ||
m_mouse_down = false; | m_mouse_down = false; | ||
} | } | ||
private: | private: | ||
TitleBar *m_titleBar; | TitleBar *m_titleBar; | ||
Line 4,270: | Line 4,101: | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
Frame box; | Frame box; | ||
box.move(0,0); | box.move(0,0); | ||
QVBoxLayout *l = new QVBoxLayout(box.contentWidget()); | QVBoxLayout *l = new QVBoxLayout(box.contentWidget()); | ||
l->setMargin(0); | l->setMargin(0); | ||
QTextEdit *edit = new QTextEdit(box.contentWidget()); | QTextEdit *edit = new QTextEdit(box.contentWidget()); | ||
l->addWidget(edit); | l->addWidget(edit); | ||
box.show(); | box.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
Note that some strange behavior may be seen when resizing the window really | Note that some strange behavior may be seen when resizing the window really | ||
small horizonally to the right on Windows (the window will start moving | small horizonally to the right on Windows (the window will start moving | ||
instead of resizing). This is due to limitations on Windows and there is | instead of resizing). This is due to limitations on Windows and there is | ||
nothing we can do about this unfortunately. | nothing we can do about this unfortunately. | ||
===How can I specify a default location and file name that will be used if a user selects print to file, but not have print to file as the default option ?=== | ===How can I specify a default location and file name that will be used if a user selects print to file, but not have print to file as the default option ?=== | ||
When calling setOutputFileName() http://doc.qt.io/qt-5 | When calling setOutputFileName() http://doc.qt.io/qt-5/qprinter.html#setOutputFileName you can specify the default output directory for the file, but this will also cause QPrinter http://doc.qt.io/qt-5/qprinter.html to print to the file specified. If you want to specify an output directory for the file and at the same time have printing to a real printer as the default option, then this is possible to achieve. To do so you need to create a QPrintDialog http://doc.qt.io/qt-5/qprintdialog.html and if the user choose print to file the print dialog will set the output file name to a non-empty string. The programmer can then choose to look at the file name after the print dialog has been executed and pop up a filedialog or similar to specify the full path for the name. | ||
===Why are the changes made in the Language tab in the International settings not respected on the Mac?=== | ===Why are the changes made in the Language tab in the International settings not respected on the Mac?=== | ||
At the moment it is not possible to detect what language is set in the International->Language tab using QLocale http://doc.qt.io/qt-5 | At the moment it is not possible to detect what language is set in the International->Language tab using QLocale http://doc.qt.io/qt-5/qlocale.html. This has however been fixed for Qt 4.8, see this entry http://bugreports.qt.io/browse/QTBUG-190 in the Bug Tracker for more information. | ||
In Qt 4.7 and below you can figure out the preferred language using QSettings http://doc.qt.io/qt-5 | In Qt 4.7 and below you can figure out the preferred language using QSettings http://doc.qt.io/qt-5/qsettings.html. See the following example: | ||
< | <syntaxhighlight lang="cpp"> | ||
QSettings settings("apple.com"); | QSettings settings("apple.com"); | ||
QStringList sl = settings.value("AppleLanguages").toStringList(); | QStringList sl = settings.value("AppleLanguages").toStringList(); | ||
qDebug() << "Lang is " << sl.first(); | qDebug() << "Lang is " << sl.first(); | ||
</ | </syntaxhighlight> | ||
===How can I prevent the view from scrolling when the user selects an item in a view?=== | ===How can I prevent the view from scrolling when the user selects an item in a view?=== | ||
In order to only allow scrolling when the user drags the scrollbar, you can reimplement scrollTo() http://doc.qt.io/qt-5/qabstractitemview.html#scrollTo to do nothing. | In order to only allow scrolling when the user drags the scrollbar, you can reimplement scrollTo() http://doc.qt.io/qt-5/qabstractitemview.html#scrollTo to do nothing. | ||
See the following example for a demonstration: | See the following example for a demonstration: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class TableWidget : public QTableWidget | class TableWidget : public QTableWidget | ||
{ | { | ||
public: | public: | ||
TableWidget() | TableWidget() | ||
{ | { | ||
setColumnCount(15); | setColumnCount(15); | ||
setRowCount(20); | setRowCount(20); | ||
QTimer::singleShot(3000, this, SLOT(testScroll())); | QTimer::singleShot(3000, this, SLOT(testScroll())); | ||
} | } | ||
void scrollTo (const QModelIndex &index, ScrollHint hint = EnsureVisible) | void scrollTo (const QModelIndex &index, ScrollHint hint = EnsureVisible) | ||
{ } | { } | ||
}; | }; | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
TableWidget table; | TableWidget table; | ||
table.show(); | table.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===I am experiencing random crashes when running my application on Windows, what can be wrong?=== | ===I am experiencing random crashes when running my application on Windows, what can be wrong?=== | ||
Line 4,351: | Line 4,182: | ||
this problem. The only way to resolve it is to ensure that Qt and your | this problem. The only way to resolve it is to ensure that Qt and your | ||
application is built in the same mode. | application is built in the same mode. | ||
===How to prevent right mouse click selection for a QTreeWidget?=== | ===How to prevent right mouse click selection for a QTreeWidget?=== | ||
In order to prevent selection of an item when right clicking, you can reimplement QTreeWidget::mousePressEvent() http://doc.qt.io/qt-5 | In order to prevent selection of an item when right clicking, you can reimplement QTreeWidget::mousePressEvent() http://doc.qt.io/qt-5/qtreeview.html#mousePressEvent to do nothing if it is the right mouse button which is being clicked. The example below illustrates how this can be done. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class TreeWidget : public QTreeWidget | class TreeWidget : public QTreeWidget | ||
{ | { | ||
public: | public: | ||
TreeWidget() | |||
{ | |||
setColumnCount(1); | |||
QList<QTreeWidgetItem *> items; | |||
for (int i = 0; i < 10; ++i) | |||
items.append(new QTreeWidgetItem((QTreeWidget*)0, QStringList(QString(item: %1).arg(i)))); | |||
insertTopLevelItems(0, items); | |||
} | |||
void mousePressEvent(QMouseEvent *event) | |||
{ | |||
if (event->button()== Qt::RightButton) | |||
return; | |||
else | |||
QTreeWidget::mousePressEvent(event); | |||
} | |||
void contextMenuEvent(QContextMenuEvent *event) | |||
{ | |||
QMenu *menu = new QMenu(this); | |||
menu->addAction(first); | |||
menu->addAction(second); | |||
menu->addAction(third); | |||
menu->exec(QCursor::pos()); | |||
} | |||
}; | }; | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
TreeWidget box; | |||
box.show(); | |||
return app.exec(); | |||
}</ | }</syntaxhighlight> | ||
Line 4,428: | Line 4,259: | ||
===Is it possible to suppress the scaling of the background of QGraphicsView?=== | ===Is it possible to suppress the scaling of the background of QGraphicsView?=== | ||
If you use setBackgroundBrush() http://doc.qt.io/qt-5/qgraphicsscene.html#backgroundBrush-prop instead of drawBackground() http://doc.qt.io/qt-5 | If you use setBackgroundBrush() http://doc.qt.io/qt-5/qgraphicsscene.html#backgroundBrush-prop instead of drawBackground() http://doc.qt.io/qt-5/qgraphicsscene.html#drawBackground on the QGraphicsScene http://doc.qt.io/qt-5/qgraphicsscene.html, you get a static background that does not scale or transform. QBrush http://doc.qt.io/qt-5/qbrush.html can take a QImage http://doc.qt.io/qt-5/qimage.html, QPixmap http://doc.qt.io/qt-5/qpixmap.html, a solid color, different gradients and different patterns. | ||
===How can I add version information to my application?=== | ===How can I add version information to my application?=== | ||
Line 4,437: | Line 4,268: | ||
When creating a .dll with a version number embedded then this is done by setting | When creating a .dll with a version number embedded then this is done by setting | ||
< | <syntaxhighlight>VERSION = x.y.z.</syntaxhighlight> | ||
in the .pro file. This will also cause the major version number to automatically be placed in the target filename. For example, when setting | in the .pro file. This will also cause the major version number to automatically be placed in the target filename. For example, when setting | ||
< | <syntaxhighlight>VERSION = 2.0.5 | ||
TARGET = mylib</ | TARGET = mylib</syntaxhighlight> | ||
the output file is called mylib2.dll. | the output file is called mylib2.dll. | ||
Line 4,448: | Line 4,279: | ||
In order to remove the version number from the target name, then you can use the TARGET_EXT http://doc.qt.io/qt-5/qmake-variable-reference.html#target-ext variable. For instance, setting the output filename without the major version number on Windows can be done by setting it like this: | In order to remove the version number from the target name, then you can use the TARGET_EXT http://doc.qt.io/qt-5/qmake-variable-reference.html#target-ext variable. For instance, setting the output filename without the major version number on Windows can be done by setting it like this: | ||
< | <syntaxhighlight>TARGET_EXT = .dll</syntaxhighlight> | ||
On Windows, you can alternatively create a resource file http://doc.qt.io/qt-5/qmake-variable-reference.html#rc-file and specify this as part of your application using: | On Windows, you can alternatively create a resource file http://doc.qt.io/qt-5/qmake-variable-reference.html#rc-file and specify this as part of your application using: | ||
< | <syntaxhighlight>RC_FILE = foo.rc</syntaxhighlight> | ||
Note that the version information will not be part of the target filename. | |||
===OpenGL and translucent background do not work together due to a limitation=== | ===OpenGL and translucent background do not work together due to a limitation=== | ||
Line 4,465: | Line 4,296: | ||
To work around this issue you can either just use Qt to render everything and not OpenGL, or you can render the OpenGL into a pixmap and draw that onto your widget instead. | To work around this issue you can either just use Qt to render everything and not OpenGL, or you can render the OpenGL into a pixmap and draw that onto your widget instead. | ||
===The eclipse integration will not install when using Wascana Desktop Developer, what can be wrong?=== | ===The eclipse integration will not install when using Wascana Desktop Developer, what can be wrong?=== | ||
Line 4,472: | Line 4,303: | ||
filename and cannot find the correct executable. To work around this you can | filename and cannot find the correct executable. To work around this you can | ||
add a dummy file called eclipse.exe to the eclipse directory. | add a dummy file called eclipse.exe to the eclipse directory. | ||
===I get errors when building my Qt/Windows project where one of my paths appears to be cut off, what can be wrong?=== | ===I get errors when building my Qt/Windows project where one of my paths appears to be cut off, what can be wrong?=== | ||
Line 4,480: | Line 4,311: | ||
installed Qt into a directory with spaces in it then Qt needs to be | installed Qt into a directory with spaces in it then Qt needs to be | ||
reinstalled into a path without spaces. | reinstalled into a path without spaces. | ||
===How can I clone a widget?=== | ===How can I clone a widget?=== | ||
Line 4,492: | Line 4,323: | ||
makes a new one. Then the function needs to copy the attributes across and | makes a new one. Then the function needs to copy the attributes across and | ||
then recurse down the widget tree. | then recurse down the widget tree. | ||
===What does the syntax CONFIG(debug,debug|release) mean ? What does the 1st argument specify and similarly what is the 2nd ?=== | ===What does the syntax CONFIG(debug,debug|release) mean ? What does the 1st argument specify and similarly what is the 2nd ?=== | ||
When qmake http://doc.qt.io/qt-5 | When qmake http://doc.qt.io/qt-5/qmake-manual.html processes a pro file it could process it up to three times depending on what the configuration is set to. Usually it will do it three times. Once for debug, once for release and one final one for debug_and_release. This is so that both configurations can be generated for at the same time. Therefore when it is required to have debug/release specific settings in a pro file then there is a need to check if qmake is processing the pro file with a particular configuration in mind. As debug and release might be in CONFIG at the same time a check for just debug or release is likely to always be true (particularly if you have debug_and_release enabled). So, this construct | ||
< | <syntaxhighlight> | ||
CONFIG(debug, debug|release) { | CONFIG(debug, debug|release) { | ||
HEADERS += debug.h | |||
SOURCES += debug.c | |||
}</ | } | ||
</syntaxhighlight> | |||
checks for when the debug configuration is being processed comparing where debug and release are mutually exclusive. As CONFIGs are order dependent (ie the last one set will be considered the active config for mutual exclusive sets like debug and release) a second parameter can be used to specify a set of values to consider, for example: | checks for when the debug configuration is being processed comparing where debug and release are mutually exclusive. As CONFIGs are order dependent (ie the last one set will be considered the active config for mutual exclusive sets like debug and release) a second parameter can be used to specify a set of values to consider, for example: | ||
< | <syntaxhighlight> | ||
message(Debug bulid) | CONFIG = debug | ||
} | CONFIG += release | ||
else:build_pass { | CONFIG(release, debug|release): message(Release build!)#will be displayed | ||
message(Release build) | CONFIG(debug, debug|release): message(Debug build!) #not displayed | ||
}</ | </syntaxhighlight> | ||
Note that you should use the build_pass variable http://doc.qt.io/qt-5/qmake-variable-reference.html to filter out messages, otherwise you will get messages when it creates the Makefile which will be the configuration specific makefile. When adding the build_pass variable in conjunction with the following scope | |||
<syntaxhighlight> | |||
build_pass:CONFIG(debug, debug|release) { | |||
message(Debug bulid) | |||
} else:build_pass { | |||
message(Release build) | |||
} | |||
</syntaxhighlight> | |||
the output will be as follows: | the output will be as follows: | ||
Project MESSAGE: Debug build | <syntaxhighlight> | ||
Project MESSAGE: Release build | Project MESSAGE: Debug build | ||
Project MESSAGE: Release build | |||
</syntaxhighlight> | |||
===How can I add a non-resource image to a QTextDocument?=== | ===How can I add a non-resource image to a QTextDocument?=== | ||
You can add a non-resource image to a QTextDocument http://doc.qt.io/qt-5 | You can add a non-resource image to a QTextDocument http://doc.qt.io/qt-5/qtextdocument.html by using the internal class QTextObjectInterface http://doc.qt.io/qt-5/qtextobjectinterface.html for inserting custom objects into a QTextDocument. | ||
The subclass of QTextObjectInterface will result in a handler for the object you would want to draw. Information like the name of the pixmap or geometry information is stored in the QTextFormat http://doc.qt.io/qt-5/qtextformat.html that you specify at QTextCursor::insertText() http://doc.qt.io/qt-5/4.7/qtextcursor.html#insertText time and that are used as arguments to the functions of QTextObjectInterface. See the documentation: | The subclass of QTextObjectInterface will result in a handler for the object you would want to draw. Information like the name of the pixmap or geometry information is stored in the QTextFormat http://doc.qt.io/qt-5/qtextformat.html that you specify at QTextCursor::insertText() http://doc.qt.io/qt-5/4.7/qtextcursor.html#insertText time and that are used as arguments to the functions of QTextObjectInterface. See the documentation: | ||
Line 4,537: | Line 4,372: | ||
See the following example for an illustration: | See the following example for an illustration: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class MyHandler : public QObject, public QTextObjectInterface | class MyHandler : public QObject, public QTextObjectInterface | ||
{ | { | ||
Q_OBJECT | Q_OBJECT | ||
Q_INTERFACES(QTextObjectInterface) | Q_INTERFACES(QTextObjectInterface) | ||
public: | public: | ||
MyHandler(QObject* par = | MyHandler(QObject* par = nullptr) : QObject(par), px("polygon.png") {} | ||
QSizeF intrinsicSize(QTextDocument *doc, int posInDoc, const QTextFormat &fmt) | QSizeF intrinsicSize(QTextDocument *doc, int posInDoc, const QTextFormat &fmt) | ||
{ | { | ||
Q_UNUSED(doc) | Q_UNUSED(doc) | ||
Q_UNUSED(posInDoc) | Q_UNUSED(posInDoc) | ||
Q_UNUSED(fmt) | Q_UNUSED(fmt) | ||
return QSizeF(px.size() ); | return QSizeF(px.size() ); | ||
} | } | ||
void drawObject(QPainter* p, const QRectF &rect, QTextDocument *doc, | void drawObject(QPainter* p, const QRectF &rect, QTextDocument *doc, | ||
int posInDoc, const QTextFormat &fmt) | int posInDoc, const QTextFormat &fmt) | ||
{ | { | ||
Q_UNUSED(doc) | Q_UNUSED(doc) | ||
Q_UNUSED(posInDoc) | Q_UNUSED(posInDoc) | ||
Q_UNUSED(fmt) | Q_UNUSED(fmt) | ||
p->drawPixmap(rect.toRect(), px ); | p->drawPixmap(rect.toRect(), px ); | ||
} | } | ||
private: | private: | ||
QPixmap px; | QPixmap px; | ||
}; | }; | ||
class Widget : public QTextEdit | class Widget : public QTextEdit | ||
{ | { | ||
public: | public: | ||
Widget(QWidget* parent = | Widget(QWidget* parent = nullptr) : QTextEdit(parent) | ||
{ | { | ||
MyHandler* handler = new MyHandler(this); | MyHandler* handler = new MyHandler(this); | ||
document()->documentLayout()->registerHandler(QTextCharFormat::UserObject, | document()->documentLayout()->registerHandler(QTextCharFormat::UserObject, | ||
handler); | handler); | ||
QTextCharFormat fmt; | QTextCharFormat fmt; | ||
fmt.setObjectType(QTextCharFormat::UserObject); | fmt.setObjectType(QTextCharFormat::UserObject); | ||
textCursor().insertText("hello"); | textCursor().insertText("hello"); | ||
textCursor().insertText(QString(QChar::ObjectReplacementCharacter), fmt); | textCursor().insertText(QString(QChar::ObjectReplacementCharacter), fmt); | ||
textCursor().insertText("world"); | textCursor().insertText("world"); | ||
} | } | ||
}; | }; | ||
#include "main.moc" | #include "main.moc" | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication a(argc, argv); | QApplication a(argc, argv); | ||
Widget w; | Widget w; | ||
w.show(); | w.show(); | ||
return a.exec(); | return a.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I modify the color for individual words for items in a view?=== | ===How can I modify the color for individual words for items in a view?=== | ||
In order to change the color for only some of the words or characters in an item, you need to draw the item yourself. This can be done by subclassing QStyledItemDelegate http://doc.qt.io/qt-5 | In order to change the color for only some of the words or characters in an item, you need to draw the item yourself. This can be done by subclassing QStyledItemDelegate http://doc.qt.io/qt-5/qstyleditemdelegate.html and reimplementing paint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#paint to draw the text using QPainter::drawText() http://doc.qt.io/qt-5/qpainter.html#drawText-9. | ||
The example below demonstrates how this can be done: | The example below demonstrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class ItemDelegate: public | class ItemDelegate: public QStyledItemDelegate | ||
{ | { | ||
public: | public: | ||
using QStyledItemDelegate::QStyledItemDelegate; | |||
void paint(QPainter *painter, const QStyleOptionViewItem &option, | void paint(QPainter *painter, const QStyleOptionViewItem &option, | ||
const QModelIndex &index) const | const QModelIndex &index) const override | ||
{ | { | ||
if(index.row() == 0 ) { | if (index.row() == 0) { | ||
QRect r; | QRect r; | ||
painter->drawText(option.rect,Qt::TextSingleLine, "Item ", &r); | painter->drawText(option.rect,Qt::TextSingleLine, "Item ", &r); | ||
painter->setPen(Qt::red); | painter->setPen(Qt::red); | ||
QRect modOptRect = option.rect; | QRect modOptRect = option.rect; | ||
modOptRect.setLeft(option.rect.left() + r.width()); | modOptRect.setLeft(option.rect.left() + r.width()); | ||
painter->drawText(modOptRect, "1"); | painter->drawText(modOptRect, "1"); | ||
} else { | } else { | ||
QItemDelegate::paint(painter, option, index); | QItemDelegate::paint(painter, option, index); | ||
} | } | ||
} | } | ||
}; | }; | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
QTreeWidget tree; | QTreeWidget tree; | ||
tree.setItemDelegate(new ItemDelegate); | tree.setItemDelegate(new ItemDelegate); | ||
QTreeWidgetItem *item1= new QTreeWidgetItem(); | QTreeWidgetItem *item1= new QTreeWidgetItem(); | ||
QTreeWidgetItem *item2= new QTreeWidgetItem(); | QTreeWidgetItem *item2= new QTreeWidgetItem(); | ||
item2->setText(0, "item 2"); | item2->setText(0, "item 2"); | ||
tree.addTopLevelItem(item1); | tree.addTopLevelItem(item1); | ||
tree.addTopLevelItem(item2); | tree.addTopLevelItem(item2); | ||
tree.show(); | tree.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===What kind of font support does Qt for Embedded Linux offer?=== | ===What kind of font support does Qt for Embedded Linux offer?=== | ||
Qt for Embedded Linux has support for TrueType, Postscrip Type1, Windows font files, and | Qt for Embedded Linux has support for TrueType, Postscrip Type1, Windows font files, and | ||
BDF fonts, both anti-aliased and conventional. The fonts can be pre-rendered for CPU and storage savings. The fonts are shared between applications. New font engines can easily be added. | BDF fonts, both anti-aliased and conventional. The fonts can be pre-rendered for CPU and storage savings. The fonts are shared between applications. New font engines can easily be added. | ||
===Does Qt for Embedded Linux offer support for internationalization?=== | ===Does Qt for Embedded Linux offer support for internationalization?=== | ||
Yes.Qt for Embedded Linux incorporates all the Qt 4 features that greatly simplify the | Yes.Qt for Embedded Linux incorporates all the Qt 4 features that greatly simplify the | ||
internationalization process, including: language and font-aware layout, extensive Unicode support, bi-directional language support, and mixed international text all in one document. | internationalization process, including: language and font-aware layout, extensive Unicode support, bi-directional language support, and mixed international text all in one document. | ||
===Is a GUI software design tool provided with Qt for Embedded Linux?=== | ===Is a GUI software design tool provided with Qt for Embedded Linux?=== | ||
Yes. Qt for Embedded Linux includes Qt Designer http://doc.qt.io/qt-5 | Yes. Qt for Embedded Linux includes Qt Designer http://doc.qt.io/qt-5/designer-manual.html, the powerful GUI layout and forms builder. Designer files can be generated on Windows, x11 (or Mac) platforms and still be used in Qt for Embedded Linux programs. | ||
===What is the difference between Qt for Embedded Linux and Qt/X11?=== | ===What is the difference between Qt for Embedded Linux and Qt/X11?=== | ||
Line 4,657: | Line 4,492: | ||
graphics performance. Nonetheless, the API for developing applications is the | graphics performance. Nonetheless, the API for developing applications is the | ||
same for Qt/X11 and Qt for Embedded Linux. | same for Qt/X11 and Qt for Embedded Linux. | ||
===Can Qt for Embedded Linux display on landscape displays in portrait orientation and visa versa?=== | ===Can Qt for Embedded Linux display on landscape displays in portrait orientation and visa versa?=== | ||
Yes. Qt for Embedded Linux supports 90, 180 and 270 degree rotation. It is simple to add | Yes. Qt for Embedded Linux supports 90, 180 and 270 degree rotation. It is simple to add | ||
additional transformations if needed. | additional transformations if needed. | ||
===Does Qt for Embedded Linux support any screen size?=== | ===Does Qt for Embedded Linux support any screen size?=== | ||
Yes. Qt for Embedded Linux handles screen sizes from very small to very large screens | Yes. Qt for Embedded Linux handles screen sizes from very small to very large screens | ||
such as 4000x4000 pixels. | such as 4000x4000 pixels. | ||
===How do I run Qt for Embedded Linux applications without a keyboard?=== | ===How do I run Qt for Embedded Linux applications without a keyboard?=== | ||
Run the application with the -nokeyboard option. | Run the application with the -nokeyboard option. | ||
===In Qt for Embedded Linux, when I create a pen with the style Qt::DashLine and a width of greater than 1, it does not appear to work in QPainter::drawLine(). Is that a limitation of the embedded library?=== | ===In Qt for Embedded Linux, when I create a pen with the style Qt::DashLine and a width of greater than 1, it does not appear to work in QPainter::drawLine(). Is that a limitation of the embedded library?=== | ||
This is the expected behaviour, caused by the internal structure of the embedded paint engine which is not as complete as that of other platforms. | This is the expected behaviour, caused by the internal structure of the embedded paint engine which is not as complete as that of other platforms. | ||
===What kind of IDEs can be used with Qt for Embedded Linux?=== | ===What kind of IDEs can be used with Qt for Embedded Linux?=== | ||
Qt for Embedded Linux applications can be developed in full-fledged IDEs such as Qt Creator, Eclipse, KDevelop or other X11 IDEs. Both Eclipse and KDevelop support auto-completion of code and debugging. Most of Qt for Embedded Linux application development can also be done on Windows using Visual studio. | Qt for Embedded Linux applications can be developed in full-fledged IDEs such as Qt Creator, Eclipse, KDevelop or other X11 IDEs. Both Eclipse and KDevelop support auto-completion of code and debugging. Most of Qt for Embedded Linux application development can also be done on Windows using Visual studio. | ||
===Does the Qt for Embedded Linux graphics subsystem have the capability write the updates only to the frame buffer, or does it always update the complete frame buffer?=== | ===Does the Qt for Embedded Linux graphics subsystem have the capability write the updates only to the frame buffer, or does it always update the complete frame buffer?=== | ||
Qt for Embedded Linux automatically updates only what has changed, **not** the complete frame. | Qt for Embedded Linux automatically updates only what has changed, **not** the complete frame. | ||
===How do I enable the touch screen in Qt for Embedded Linux?=== | ===How do I enable the touch screen in Qt for Embedded Linux?=== | ||
Line 4,693: | Line 4,528: | ||
Additionally Qt for Embedded Linux has support for tslib which indicates that any touch screen supported by tslib can be used in Qt. | Additionally Qt for Embedded Linux has support for tslib which indicates that any touch screen supported by tslib can be used in Qt. | ||
===Can I execute a Qt for Embedded Linux application on my development PC although my X-server is running?=== | ===Can I execute a Qt for Embedded Linux application on my development PC although my X-server is running?=== | ||
Yes, by using the Qt Virtual Framebuffer (QVFb). | Yes, by using the Qt Virtual Framebuffer (QVFb). | ||
===Why do I receive the following error message when building makeqpf: Some of the required modules (nocrosscompiler) are not available.=== | ===Why do I receive the following error message when building makeqpf: Some of the required modules (nocrosscompiler) are not available.=== | ||
Line 4,706: | Line 4,541: | ||
This does not mean that you cannot cross-compile Qt for Embedded Linux. Copy the Qt for Embedded Linux directory, and let one be compiled for your local system and another one for your target system. | This does not mean that you cannot cross-compile Qt for Embedded Linux. Copy the Qt for Embedded Linux directory, and let one be compiled for your local system and another one for your target system. | ||
===Can I develop software with Qt/X11 or Qt/Windows and easily change to Qt for Embedded Linux?=== | ===Can I develop software with Qt/X11 or Qt/Windows and easily change to Qt for Embedded Linux?=== | ||
Line 4,712: | Line 4,547: | ||
4.x, so any program working with Qt 4.x will work with Qt for Embedded Linux (as long as | 4.x, so any program working with Qt 4.x will work with Qt for Embedded Linux (as long as | ||
it does not contain platform-dependent code, of course). | it does not contain platform-dependent code, of course). | ||
===Is an X server required for Qt for Embedded Linux?=== | ===Is an X server required for Qt for Embedded Linux?=== | ||
No. Qt for Embedded Linux always runs without an X server. Any Qt for Embedded Linux application can function as the master process, which is not a graphics server like X11 that handles device input and window allocation. | No. Qt for Embedded Linux always runs without an X server. Any Qt for Embedded Linux application can function as the master process, which is not a graphics server like X11 that handles device input and window allocation. | ||
===What is a standard way of configuring Qt/e for a desktop system used for developing Qt for Embedded Linux applications?=== | ===What is a standard way of configuring Qt/e for a desktop system used for developing Qt for Embedded Linux applications?=== | ||
Line 4,732: | Line 4,567: | ||
./configure -qvfb -embedded x86 -debug -depths 8,16,32 -thread -shared. | ./configure -qvfb -embedded x86 -debug -depths 8,16,32 -thread -shared. | ||
===What are the graphics capabilities of Qt for Embedded Linux?=== | ===What are the graphics capabilities of Qt for Embedded Linux?=== | ||
Qt for Embedded Linux's graphics subsystem provides everything needed to create state-of-the-art user interfaces, including: | Qt for Embedded Linux's graphics subsystem provides everything needed to create state-of-the-art user interfaces, including: | ||
* support for semi-transparency (alpha-blending) and anti-aliasing | * support for semi-transparency (alpha-blending) and anti-aliasing | ||
Line 4,741: | Line 4,576: | ||
* optional floating-point coordinate system | * optional floating-point coordinate system | ||
* painter paths | * painter paths | ||
* gradients | * gradients | ||
* support for interchangeable underlying paint engines and off-screen rendering. | * support for interchangeable underlying paint engines and off-screen rendering. | ||
* Qt for Embedded Linux integrates SVG 1.1/1.2 Tiny drawings and animations, and additional features for developers using OpenGL. | * Qt for Embedded Linux integrates SVG 1.1/1.2 Tiny drawings and animations, and additional features for developers using OpenGL. | ||
===How do I add true-type fonts when migrating my application from Qt-X11 to Qt for Embedded Linux?=== | ===How do I add true-type fonts when migrating my application from Qt-X11 to Qt for Embedded Linux?=== | ||
Line 4,754: | Line 4,589: | ||
For further information see: http://doc.qt.io/qt-5/qt-embedded-fonts.html | For further information see: http://doc.qt.io/qt-5/qt-embedded-fonts.html | ||
===Why do I receive the QVFb Driver Not Found message when running a Qt for Embedded Linux application?=== | ===Why do I receive the QVFb Driver Not Found message when running a Qt for Embedded Linux application?=== | ||
Line 4,761: | Line 4,596: | ||
To solve the problem, start QVFb before you start the application. | To solve the problem, start QVFb before you start the application. | ||
===Why does the compilation of Qt for Embedded Linux fail with the message: dialogs/qprintdialog.cpp:790: cups/cups.h: No such file or directory?=== | ===Why does the compilation of Qt for Embedded Linux fail with the message: dialogs/qprintdialog.cpp:790: cups/cups.h: No such file or directory?=== | ||
Line 4,767: | Line 4,602: | ||
problem should be solved. If you do not need cups, you can configure Qt with | problem should be solved. If you do not need cups, you can configure Qt with | ||
the option -no-cups. | the option -no-cups. | ||
===Is there a way to get access to the virtual framebuffer inside a QPixmap, so that we can render to this address, and then blt the result to screen?=== | ===Is there a way to get access to the virtual framebuffer inside a QPixmap, so that we can render to this address, and then blt the result to screen?=== | ||
Yes. It is Qt for Embedded Linux specific, but you can obtain a pointer to the bits of a QPixmap http://doc.qt.io/qt-5/qpixmap.html. For example: | Yes. It is Qt for Embedded Linux specific, but you can obtain a pointer to the bits of a QPixmap http://doc.qt.io/qt-5/qpixmap.html. For example: | ||
< | <syntaxhighlight lang="cpp"> | ||
void SomeClass::someFunc(){ | void SomeClass::someFunc(){ | ||
#ifdef Q_WS_QWS | #ifdef Q_WS_QWS | ||
Line 4,779: | Line 4,614: | ||
int bytesPerLine = pm.bytesPerLine(); | int bytesPerLine = pm.bytesPerLine(); | ||
#endif | #endif | ||
</ | </syntaxhighlight> | ||
} | } | ||
===How can I add an accelerated graphics driver?=== | ===How can I add an accelerated graphics driver?=== | ||
Qt for Embedded Linux has the capacity to make use of hardware accelerators. To do so for a PCI or an AGP driver, you need to perform the steps outlined in this document http://doc.qt.io/qt-5/qt-embedded-accel.html. | Qt for Embedded Linux has the capacity to make use of hardware accelerators. To do so for a PCI or an AGP driver, you need to perform the steps outlined in this document http://doc.qt.io/qt-5/qt-embedded-accel.html. | ||
===Why is it not allowed to copy QObjects?=== | ===Why is it not allowed to copy QObjects?=== | ||
The reason it is not possible to copy QObjects http://doc.qt.io/qt-5 | The reason it is not possible to copy QObjects http://doc.qt.io/qt-5/qobject.html is that QObject is a polymorphic object, and that polymorphic objects cannot be copied. | ||
< | <syntaxhighlight lang="cpp"> | ||
QPushButton pushButton; | QPushButton pushButton; | ||
QObject object = pushButton; | QObject object = pushButton; | ||
Q_ASSERT(object.metaObject() == &QPushButton::staticMetaObject) | Q_ASSERT(object.metaObject() == &QPushButton::staticMetaObject) | ||
</ | </syntaxhighlight> | ||
This would assert, and all calls of virtual functions would call QObject's implementation. | This would assert, and all calls of virtual functions would call QObject's implementation. | ||
===Are there any tools for the job of converting Windows MFC dialogs?="Yes, the GUI layout of Windows dialogs can to some degree be automatically translated to the Qt equivalent using KDAB's tool KNUT() http://www.klaralvdalens-datakonsult.se/?page=products&sub=== | ===Are there any tools for the job of converting Windows MFC dialogs?="Yes, the GUI layout of Windows dialogs can to some degree be automatically translated to the Qt equivalent using KDAB's tool KNUT() http://www.klaralvdalens-datakonsult.se/?page=products&sub=== | ||
Line 4,803: | Line 4,638: | ||
===Is it possible to set a header and footer when printing a QTextDocument?=== | ===Is it possible to set a header and footer when printing a QTextDocument?=== | ||
Line 4,810: | Line 4,645: | ||
The following is an example of how it can be implemented: | The following is an example of how it can be implemented: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
Line 4,851: | Line 4,686: | ||
return 0; | return 0; | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How do I run a Qt for Embedded Linux application without a mouse?=== | ===How do I run a Qt for Embedded Linux application without a mouse?=== | ||
Run your embedded application with the option: -nomouse , this disables the | Run your embedded application with the option: -nomouse , this disables the | ||
mouse. | mouse. | ||
===Can I use Qt for Embedded Linux on a PXA27x development board with our own version of Linux?=== | ===Can I use Qt for Embedded Linux on a PXA27x development board with our own version of Linux?=== | ||
Line 4,866: | Line 4,701: | ||
to your graphics hardware. Qt for Embedded Linux has a specific plug-in API for adding | to your graphics hardware. Qt for Embedded Linux has a specific plug-in API for adding | ||
your own graphics driver. | your own graphics driver. | ||
===My Qt/Windows application is running out of user handles, as the application contains a huge amount of widgets. What can be done about this ?=== | ===My Qt/Windows application is running out of user handles, as the application contains a huge amount of widgets. What can be done about this ?=== | ||
Line 4,885: | Line 4,720: | ||
http://labs.trolltech.com/blogs/2007/08/09/qt-invaded-by-aliens-the-end-of-all-flicker | http://labs.trolltech.com/blogs/2007/08/09/qt-invaded-by-aliens-the-end-of-all-flicker | ||
===Parentheses show up incorrectly for English text in a right-to-left application. What is wrong?=== | ===Parentheses show up incorrectly for English text in a right-to-left application. What is wrong?=== | ||
In -reverse mode or when calling | In -reverse mode or when calling | ||
< | <syntaxhighlight lang="cpp">setLayoutDirection(Qt::RightToLeft)</syntaxhighlight> | ||
the default text direction is RightToLeft http://doc.qt.io/qt-5 | the default text direction is RightToLeft http://doc.qt.io/qt-5/qt.html#LayoutDirection-enum. The display is how the Bidirectional Algorithm http://unicode.org/reports/tr9 defines the output should look. | ||
Using -reverse together with English text will result in some artifacts like this. It's the task of the translator to ensure things look correct in a right to left language. He can do that by adding some special Unicode characters to the translated string (left-to-right marks etc). In Linguist http://doc.qt.io/qt-5/linguist-manual.html, this can be done by right clicking in the translation field and selecting Insert Unicode control character/LRM Left-to-Right mark. | |||
===Is there a way to modify the window flags without causing flicker?=== | ===Is there a way to modify the window flags without causing flicker?=== | ||
It is not possible to make changes to the window flags once the window has been created without causing flicker. Flicker is unavoidable since the window needs to be recreated. | It is not possible to make changes to the window flags once the window has been created without causing flicker. Flicker is unavoidable since the window needs to be recreated. | ||
===How can I change the width of the scrollbar of QWebView?=== | ===How can I change the width of the scrollbar of QWebView?=== | ||
The stylesheet API does not yet support styling QWebView http://doc.qt.io/qt-5 | The stylesheet API does not yet support styling QWebView http://doc.qt.io/qt-5/qwebview.html, but you can style the webview's scrollbar using the style API. | ||
You can subclass your style (or create a proxy style) and reimplement QStyle::pixelMetric() http://doc.qt.io/qt-5 | You can subclass your style (or create a proxy style) and reimplement QStyle::pixelMetric() http://doc.qt.io/qt-5/qstyle.html#pixelMetric to return the width you want when the metric is QStyle::PM_ScrollBarExtent http://doc.qt.io/qt-5/qstyle.html#PixelMetric-enum. QWebView does not actually use a QScrollBar http://doc.qt.io/qt-5/qscrollbar.html, so you need to be a bit sneaky here to get this to work. When QStyle::pixelMetric() is called in this case, the QWidget* http://doc.qt.io/qt-5/qwidget.html passed in is 0 whereas it is the scrollbar in other cases. So you could set the style on the application and check if the widget is 0 in QStyle::pixelMetric(). If it is, you can assume it's the webview asking for it and therefore returning your modified size and if not fall back to the base class. | ||
The example below demonstrates how this can be done: | The example below demonstrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
#include <QWebView> | #include <QWebView> | ||
Line 4,919: | Line 4,754: | ||
{ | { | ||
public: | public: | ||
Style() | Style() {} | ||
int pixelMetric (PixelMetric metric, const QStyleOption *option = nullptr, const QWidget *widget = nullptr) const | |||
int pixelMetric ( PixelMetric metric, const QStyleOption * option = | |||
{ | { | ||
if (metric == QStyle::PM_ScrollBarExtent && widget == | if (metric == QStyle::PM_ScrollBarExtent && widget == nullptr) | ||
return 30; | return 30; | ||
return QWindowsStyle::pixelMetric(metric, option, widget); | return QWindowsStyle::pixelMetric(metric, option, widget); | ||
Line 4,949: | Line 4,782: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===I get an 'Error while parsing /XXX/qrc_XXX.cpp, Java Heap Space'. What's the problem ?=== | ===I get an 'Error while parsing /XXX/qrc_XXX.cpp, Java Heap Space'. What's the problem ?=== | ||
Line 4,957: | Line 4,790: | ||
eclipse -vmargs -Xmx1000M | eclipse -vmargs -Xmx1000M | ||
===Is there a way of sizing the window so that it is never overlapped by the taskbar (or it doesn't overlap the taskbar)?=== | ===Is there a way of sizing the window so that it is never overlapped by the taskbar (or it doesn't overlap the taskbar)?=== | ||
Line 4,963: | Line 4,796: | ||
The returned rect excludes the taskbar, so as long as you use only that geometry, you can be sure that your window won't be underneath or on top of the taskbar. | The returned rect excludes the taskbar, so as long as you use only that geometry, you can be sure that your window won't be underneath or on top of the taskbar. | ||
===How can I draw shadows behind windows ?=== | ===How can I draw shadows behind windows ?=== | ||
Line 4,976: | Line 4,809: | ||
There are other solutions you can use for faking this effect for windows of a static size (useful for splash screens). For instance, you can take a screenshot of the desktop widget using the following code snippet: | There are other solutions you can use for faking this effect for windows of a static size (useful for splash screens). For instance, you can take a screenshot of the desktop widget using the following code snippet: | ||
< | <syntaxhighlight lang="cpp"> | ||
QSize SIZE(600, 300); | QSize SIZE(600, 300); | ||
QRect splashScreenRect(r.width() / 2 - SIZE.width() / 2, r.height() / 2 - SIZE.height() / 2, SIZE.width(), SIZE.height()); | QRect splashScreenRect(r.width() / 2 - SIZE.width() / 2, r.height() / 2 - SIZE.height() / 2, SIZE.width(), SIZE.height()); | ||
QPixmap desktopBg = QPixmap::grabWindow(QApplication::desktop()->winId(), splashScreenRect.x(), splashScreenRect.y(), splashScreenRect.width(), splashScreenRect.height()); | QPixmap desktopBg = QPixmap::grabWindow(QApplication::desktop()->winId(), splashScreenRect.x(), splashScreenRect.y(), splashScreenRect.width(), splashScreenRect.height()); | ||
</ | </syntaxhighlight> | ||
Then you would just draw this pixmap as normal and paint using alpha blending on top of it. | Then you would just draw this pixmap as normal and paint using alpha blending on top of it. | ||
===How can I display vertical text in the section of a QHeaderView?=== | ===How can I display vertical text in the section of a QHeaderView?=== | ||
The way to do this is to subclass QProxyStyle http://doc.qt.io/qt-5 | The way to do this is to subclass QProxyStyle http://doc.qt.io/qt-5/qproxystyle.html (or another style if don't want to fall back to the default style) and reimplement drawControl() http://doc.qt.io/qt-5/qproxystyle.html#drawControl. In this function you need to handle the CE_HeaderLabel http://doc.qt.io/qt-5/qstyle.html#ControlElement-enum case and draw the text manually after having rotated the painter. | ||
The following is an example of how to do this: | The following is an example of how to do this: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class MyStyle : public QProxyStyle | class MyStyle : public QProxyStyle | ||
Line 4,997: | Line 4,830: | ||
public: | public: | ||
MyStyle(QStyle *style) : QProxyStyle(style) {} | MyStyle(QStyle *style) : QProxyStyle(style) {} | ||
void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, | void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, | ||
const QWidget *widget = | const QWidget *widget = nulltr) const | ||
{ | { | ||
if (element == QStyle::CE_HeaderLabel) { | if (element == QStyle::CE_HeaderLabel) { | ||
Line 5,026: | Line 4,859: | ||
return a.exec(); | return a.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Why does not touching and moving work when running the imagegestures example on Windows 7?=== | ===Why does not touching and moving work when running the imagegestures example on Windows 7?=== | ||
Our gestures examples rely on the native Windows 7 gesture and touch input. If your driver doesn't generate these, then the examples won't work. One easy way to tell if it is the driver causing the problem is to put break points into the *WM_GESTURE* and *WM_TOUCH* message handlers in qapplication_win.cpp. If you hit those breakpoints, your driver supports the Windows 7 touch interface, but Qt doesn't work with it for some reason. In which case this should be reported via the usual channel http://bugreports.qt.io. Otherwise it is most likely an issue caused by your driver not implementing the Windows 7 touch interface. | Our gestures examples rely on the native Windows 7 gesture and touch input. If your driver doesn't generate these, then the examples won't work. One easy way to tell if it is the driver causing the problem is to put break points into the *WM_GESTURE* and *WM_TOUCH* message handlers in qapplication_win.cpp. If you hit those breakpoints, your driver supports the Windows 7 touch interface, but Qt doesn't work with it for some reason. In which case this should be reported via the usual channel http://bugreports.qt.io. Otherwise it is most likely an issue caused by your driver not implementing the Windows 7 touch interface. | ||
===How can I align the checkboxes in a view?=== | ===How can I align the checkboxes in a view?=== | ||
In order to align the checkboxes in a view, you need to create your own QStyledItemDelegate http://doc.qt.io/qt-5 | In order to align the checkboxes in a view, you need to create your own QStyledItemDelegate http://doc.qt.io/qt-5/qstyleditemdelegate.html and reimplement paint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#paint to draw the checkboxes with the alignment that you want. | ||
In order to do this, QStyle::alignedRect() http://doc.qt.io/qt-5 | In order to do this, QStyle::alignedRect() http://doc.qt.io/qt-5/qstyle.html#alignedRect is used to ensure that it is correctly aligned in the center of the rect for the index, then the base implementation is called with the new information so it takes care of rendering the checkbox. | ||
It is also necessary to reimplement QStyledItemDelegate::editorEvent() http://doc.qt.io/qt-5/qabstractitemdelegate.html#editorEvent to handle the toggling of the checkbox correctly since the checkbox has actually been moved to a different position, and therefore the events for the index need to be handled correctly. | It is also necessary to reimplement QStyledItemDelegate::editorEvent() http://doc.qt.io/qt-5/qabstractitemdelegate.html#editorEvent to handle the toggling of the checkbox correctly since the checkbox has actually been moved to a different position, and therefore the events for the index need to be handled correctly. | ||
The following example demonstrates how this can be done: | The following example demonstrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class ItemDelegate : public QStyledItemDelegate | class ItemDelegate : public QStyledItemDelegate | ||
{ | { | ||
public: | public: | ||
ItemDelegate(QObject *parent = | ItemDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {} | ||
void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const | void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override | ||
{ | { | ||
QStyleOptionViewItem viewItemOption(option); | |||
if (index.column() == 0) { | if (index.column() == 0) { | ||
Line 5,068: | Line 4,898: | ||
} | } | ||
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, | |||
const QModelIndex &index) override | |||
{ | { | ||
Q_ASSERT(event); | Q_ASSERT(event); | ||
Line 5,110: | Line 4,940: | ||
Q_OBJECT | Q_OBJECT | ||
public: | public: | ||
Table(QWidget *parent = | Table(QWidget *parent = nullptr) | ||
: QTableWidget(ROWS, COLS, parent) | : QTableWidget(ROWS, COLS, parent) | ||
{ | { | ||
Line 5,134: | Line 4,964: | ||
return a.exec(); | return a.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I dynamically switch between languages in my application using e.g a QComboBox?=== | ===How can I dynamically switch between languages in my application using e.g a QComboBox?=== | ||
In order to achieve this, you can create a function, called e.g retranslateUi() that sets the user visible text for your widgets. It is not possible to switch between the languages without having such a function that gets called every time the language is changed and that returns a translated version of the text by wrapping it with tr() http://doc.qt.io/qt-5 | In order to achieve this, you can create a function, called e.g retranslateUi() that sets the user visible text for your widgets. It is not possible to switch between the languages without having such a function that gets called every time the language is changed and that returns a translated version of the text by wrapping it with tr() http://doc.qt.io/qt-5/qobject.html#tr. | ||
Now you can connect the activated() http://doc.qt.io/qt-5 | Now you can connect the activated() http://doc.qt.io/qt-5/qcombobox.html#activated signal of your QComboBox to a slot which will load and install the correct translator. Finally you also need to reimplement the changeEvent() http://doc.qt.io/qt-5/qcombobox.html#changeEvent to check for a LanguageChange http://doc.trolltech.com/qevent.html#Type-enum event and call retranslateUi() when it occurs . | ||
See the following example for a demonstration: | See the following example for a demonstration: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class MainWindow : public QMainWindow | class MainWindow : public QMainWindow | ||
{ | { | ||
Line 5,159: | Line 4,989: | ||
menu->addAction(fileAction); | menu->addAction(fileAction); | ||
QComboBox *combo = new QComboBox(this); | QComboBox *combo = new QComboBox(this); | ||
setCentralWidget(combo); | setCentralWidget(combo); | ||
combo->addItem("fr"); | combo->addItem("fr"); | ||
combo->addItem("en"); | combo->addItem("en"); | ||
Line 5,169: | Line 4,999: | ||
{ | { | ||
menu->setTitle(tr("File")); | menu->setTitle(tr("File")); | ||
fileAction->setText(tr("First action")); | fileAction->setText(tr("First action")); | ||
} | } | ||
void changeEvent ( QEvent * event ) | void changeEvent ( QEvent * event ) | ||
Line 5,211: | Line 5,041: | ||
return a.exec(); | return a.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===When building Qt using MinGW I get the following error: Makefile.Debug:24691: *** multiple target patterns. What can be wrong?=== | ===When building Qt using MinGW I get the following error: Makefile.Debug:24691: *** multiple target patterns. What can be wrong?=== | ||
You probably have some include and lib paths that are not necessary and are causing problems, if you do: | You probably have some include and lib paths that are not necessary and are causing problems, if you do: | ||
< | <syntaxhighlight lang="cpp"> | ||
set INCLUDE= | set INCLUDE= | ||
set LIB= | set LIB= | ||
configure -redo | configure -redo | ||
mingw32-make | mingw32-make | ||
</ | </syntaxhighlight> | ||
that should solve the problem for you. | that should solve the problem for you. | ||
Line 5,228: | Line 5,058: | ||
Also, make sure that sh.exe (usually comes with Cygwin or msys) is not in the | Also, make sure that sh.exe (usually comes with Cygwin or msys) is not in the | ||
PATH either, as MinGW's make tool expects UNIX-makefiles when it is. | PATH either, as MinGW's make tool expects UNIX-makefiles when it is. | ||
===How can I span the headers in my QTableView ?=== | ===How can I span the headers in my QTableView ?=== | ||
Qt does not provide an API for spanning headers, but you can implement this yourself. You can subclass QHeaderView http://doc.qt.io/qt-5 | Qt does not provide an API for spanning headers, but you can implement this yourself. You can subclass QHeaderView http://doc.qt.io/qt-5/qheaderview.html and create one section for each of the groups of columns/rows you would like to span and connect signals and slots to have them react to the different columns/rows. | ||
The following example demonstrates how this can be done for spanning thecolumns in the horizontal header. | The following example demonstrates how this can be done for spanning thecolumns in the horizontal header. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class MyHeaderModel : public QAbstractItemModel | class MyHeaderModel : public QAbstractItemModel | ||
{ | { | ||
public: | public: | ||
MyHeaderModel(QObject *parent = | MyHeaderModel(QObject *parent = nullptr) : QAbstractItemModel(parent) {} | ||
int columnCount(const QModelIndex &parent = QModelIndex()) const { return 2; } | int columnCount(const QModelIndex &parent = QModelIndex()) const override { return 2; } | ||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const { return QVariant(); } | QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override { return QVariant(); } | ||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const { return QModelIndex(); } | QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override { return QModelIndex(); } | ||
QModelIndex parent(const QModelIndex &index) const { return QModelIndex(); } | QModelIndex parent(const QModelIndex &index) const override { return QModelIndex(); } | ||
int rowCount(const QModelIndex &parent = QModelIndex()) const { return 0; } | int rowCount(const QModelIndex &parent = QModelIndex()) const override { return 0; } | ||
}; | }; | ||
Line 5,253: | Line 5,083: | ||
Q_OBJECT | Q_OBJECT | ||
public: | public: | ||
MyHeader(QHeaderView *header, QWidget *parent = | MyHeader(QHeaderView *header, QWidget *parent = nullptr) : QHeaderView(Qt::Horizontal, header), mainHeader(header) | ||
{ | { | ||
setModel(new MyHeaderModel(this)); | setModel(new MyHeaderModel(this)); | ||
Line 5,315: | Line 5,145: | ||
return a.exec(); | return a.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How do I make text follow the line/curve and angle of the QPainterPath?=== | ===How do I make text follow the line/curve and angle of the QPainterPath?=== | ||
You can set a QTransform http://doc.qt.io/qt-5/qtransform.html on a QPainter http://doc.qt.io/qt-5/qpainter.html causing the painting to follow a transformation. The usual problem is that it's easy to rotate using QTransform::rotate() http://doc.qt.io/qt-5/4.7/qtransform.html#rotate, but since it rotates around origin which is in the top left corner, the coordinates will not match the painting done without a transformation. Using QTransform http://doc.qt.io/qt-5/qtransform.html translation, you can translate the positions back to the original position, and all of this in the name of trigonometry. | You can set a QTransform http://doc.qt.io/qt-5/qtransform.html on a QPainter http://doc.qt.io/qt-5/qpainter.html causing the painting to follow a transformation. The usual problem is that it's easy to rotate using QTransform::rotate() http://doc.qt.io/qt-5/4.7/qtransform.html#rotate, but since it rotates around origin which is in the top left corner, the coordinates will not match the painting done without a transformation. Using QTransform http://doc.qt.io/qt-5/qtransform.html translation, you can translate the positions back to the original position, and all of this in the name of trigonometry. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
#include <cmath> | #include <cmath> | ||
Line 5,409: | Line 5,239: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===When I run my Qt for Embedded Linux application I get the error message Can't drive depth 32.=== | ===When I run my Qt for Embedded Linux application I get the error message Can't drive depth 32.=== | ||
Your problem is most likely that you did not configure with support for the bit depth which the screen supports. To specify which bit depths you want Qt for Embedded Linux to support, use the configure option depths. For example: | Your problem is most likely that you did not configure with support for the bit depth which the screen supports. To specify which bit depths you want Qt for Embedded Linux to support, use the configure option depths. For example: | ||
< | <syntaxhighlight>./configure -qvfb -embedded x86 -debug -depths 8,16,32 -thread</syntaxhighlight> | ||
===I want to run my Qt for Embedded Linux application on the QVFb, but I get the message Can't open framebuffer device /dev/fb0 : driver cannot connect.=== | ===I want to run my Qt for Embedded Linux application on the QVFb, but I get the message Can't open framebuffer device /dev/fb0 : driver cannot connect.=== | ||
Line 5,422: | Line 5,252: | ||
./fooprog -qws -display LinuxFb | ./fooprog -qws -display LinuxFb | ||
===Where do I put the plug-in library file for a touch screen driver plug-in?=== | ===Where do I put the plug-in library file for a touch screen driver plug-in?=== | ||
The library should be put in yourQtDirectory/plugins/mousedrivers where it will be | The library should be put in yourQtDirectory/plugins/mousedrivers where it will be | ||
automatically found. | automatically found. | ||
===setClickable() and setSortIndicatorShown() affect the entire QHeaderView, is there a way to have it affect only certain sections?=== | ===setClickable() and setSortIndicatorShown() affect the entire QHeaderView, is there a way to have it affect only certain sections?=== | ||
There is no direct API for this at the moment, so for the time being, you need to reimplement the mousePressEvent() http://doc.qt.io/qt-5 | There is no direct API for this at the moment, so for the time being, you need to reimplement the mousePressEvent() http://doc.qt.io/qt-5/qheaderview.html#mousePressEvent and mouseReleaseEvent() http://doc.qt.io/qt-5/qheaderview.html#mouseReleaseEvent for the headerview and check which section is being pressed on, then if it is one you want to allow to be movable, or clickable, you turn it on before calling the base implementation. In the mouseReleaseEvent() you would turn off the movable/clickable properties. | ||
When it comes to setSortIndicatorShown() http://doc.qt.io/qt-5 | When it comes to setSortIndicatorShown() http://doc.qt.io/qt-5/qheaderview.html#showSortIndicator-prop, then it is expected that the indicator will be shown until the user clicks on another section. So in mousePressEvent() we hide the indicator if the section clicked is not the one that should show the indicator. Alternatively the sort indicator can simply stay on the section clicked previously. | ||
The example below demonstrates how this can be done. | The example below demonstrates how this can be done. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class HeaderView : public QHeaderView | class HeaderView : public QHeaderView | ||
{ | { | ||
Q_OBJECT | Q_OBJECT | ||
public: | public: | ||
HeaderView(QWidget *parent = | HeaderView(QWidget *parent = nullptr) : QHeaderView(Qt::Horizontal, parent) | ||
{ | { | ||
connect(this, | connect(this, &QHeaderView::sectionClicked, this, &HeaderView::clickedSection); | ||
} | } | ||
void mousePressEvent(QMouseEvent *event) | void mousePressEvent(QMouseEvent *event) override | ||
{ | { | ||
if(visualIndexAt(event->pos().x()) == 1) { | if(visualIndexAt(event->pos().x()) == 1) { | ||
Line 5,459: | Line 5,289: | ||
QHeaderView::mousePressEvent(event); | QHeaderView::mousePressEvent(event); | ||
} | } | ||
void mouseReleaseEvent(QMouseEvent *event) | void mouseReleaseEvent(QMouseEvent *event) override | ||
{ | { | ||
QHeaderView::mouseReleaseEvent(event); | QHeaderView::mouseReleaseEvent(event); | ||
Line 5,470: | Line 5,300: | ||
} | } | ||
}; | }; | ||
class TreeWidget : public QTreeWidget | class TreeWidget : public QTreeWidget | ||
{ | { | ||
Line 5,488: | Line 5,318: | ||
} | } | ||
}; | }; | ||
#include "main.moc" | #include "main.moc" | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
Line 5,498: | Line 5,328: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I debug the Qt source files when running my application inside Visual Studio?=== | ===How can I debug the Qt source files when running my application inside Visual Studio?=== | ||
Line 5,511: | Line 5,341: | ||
===How can QTextCursor be used to select a row in a QTextTable?=== | ===How can QTextCursor be used to select a row in a QTextTable?=== | ||
All that needs to be done to select the whole row is get the cells for the first and last column in the row, and then getting the relevant positions from those cells. With those positions you can select the text using setPosition() http://doc.qt.io/qt-5 | All that needs to be done to select the whole row is get the cells for the first and last column in the row, and then getting the relevant positions from those cells. With those positions you can select the text using setPosition() http://doc.qt.io/qt-5/qtextcursor.html#setPosition and keeping the anchor. An example piece of code is as follows: | ||
< | <syntaxhighlight lang="cpp"> | ||
QTextTable *tt = textEdit->textCursor().currentTable(); | QTextTable *tt = textEdit->textCursor().currentTable(); | ||
if (!tt) | if (!tt) | ||
return; | return; | ||
QTextCursor cursor = textEdit->textCursor(); | QTextCursor cursor = textEdit->textCursor(); | ||
QTextTableCell cell = tt->cellAt(cursor); | QTextTableCell cell = tt->cellAt(cursor); | ||
QTextTableCell rowStart = tt->cellAt(cell.row(), 0); | QTextTableCell rowStart = tt->cellAt(cell.row(), 0); | ||
QTextTableCell rowEnd = tt->cellAt(cell.row(), tt->columns() - 1); | QTextTableCell rowEnd = tt->cellAt(cell.row(), tt->columns() - 1); | ||
cursor.setPosition(rowStart.firstCursorPosition().position()); | cursor.setPosition(rowStart.firstCursorPosition().position()); | ||
cursor.setPosition(rowEnd.lastCursorPosition().position(), QTextCursor::KeepAnchor); | cursor.setPosition(rowEnd.lastCursorPosition().position(), QTextCursor::KeepAnchor); | ||
textEdit->setTextCursor(cursor); | textEdit->setTextCursor(cursor); | ||
</ | </syntaxhighlight> | ||
===How do I apply patch files to Qt source files?=== | ===How do I apply patch files to Qt source files?=== | ||
Line 5,540: | Line 5,370: | ||
http://gnuwin32.sourceforge.net/packages/patch.htm | http://gnuwin32.sourceforge.net/packages/patch.htm | ||
===When dragging and dropping between 2 views, how can I perform a move without pressing Shift?=== | ===When dragging and dropping between 2 views, how can I perform a move without pressing Shift?=== | ||
When dragging and dropping between 2 views then a copy will be done by default when not pressing Shift. If you need to make it a Move action instead, then you can call | When dragging and dropping between 2 views then a copy will be done by default when not pressing Shift. If you need to make it a Move action instead, then you can call | ||
< | <syntaxhighlight lang="cpp">setDropAction(Qt::MoveAction) </syntaxhighlight> | ||
in the dragEnterEvent() http://doc.qt.io/qt-5 | in the dragEnterEvent() http://doc.qt.io/qt-5/qabstractitemview.html#dragEnterEvent, dragMoveEvent() http://doc.qt.io/qt-5/qlistview.html#dragMoveEvent and the dropEvent() http://doc.qt.io/qt-5/qlistwidget.html#dropEvent. Doing so will override the proposed action http://doc.trolltech.com/dnd.html#overriding-proposed-actions. | ||
See the following example for a demonstration: | See the following example for a demonstration: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class ListWidget : public QListWidget { | class ListWidget : public QListWidget { | ||
Q_OBJECT | Q_OBJECT | ||
public: | public: | ||
ListWidget() : QListWidget(0) | ListWidget() : QListWidget(0) | ||
{ | { | ||
setAcceptDrops(true); | setAcceptDrops(true); | ||
setDragEnabled(true); | setDragEnabled(true); | ||
QListWidgetItem *item1 = new QListWidgetItem(tr("Oak"), this); | QListWidgetItem *item1 = new QListWidgetItem(tr("Oak"), this); | ||
QListWidgetItem *item2 = new QListWidgetItem(tr("Fir"), this); | QListWidgetItem *item2 = new QListWidgetItem(tr("Fir"), this); | ||
QListWidgetItem *item3 = new QListWidgetItem(tr("Pine"), this); | QListWidgetItem *item3 = new QListWidgetItem(tr("Pine"), this); | ||
} | } | ||
void dragEnterEvent(QDragEnterEvent *e) | void dragEnterEvent(QDragEnterEvent *e) | ||
{ | { | ||
QListWidget::dragEnterEvent(e); | QListWidget::dragEnterEvent(e); | ||
if (e->keyboardModifiers() == Qt::NoModifier) { e->setDropAction(Qt::MoveAction); | if (e->keyboardModifiers() == Qt::NoModifier) { e->setDropAction(Qt::MoveAction); | ||
e->accept(); | e->accept(); | ||
} else if (e->proposedAction() == Qt::MoveAction) | } else if (e->proposedAction() == Qt::MoveAction) | ||
e->acceptProposedAction(); | e->acceptProposedAction(); | ||
} | } | ||
void dragMoveEvent(QDragMoveEvent *e) | void dragMoveEvent(QDragMoveEvent *e) | ||
{ | { | ||
QListWidget::dragMoveEvent(e); | QListWidget::dragMoveEvent(e); | ||
if (e->keyboardModifiers() == Qt::NoModifier) { e->setDropAction(Qt::MoveAction); | if (e->keyboardModifiers() == Qt::NoModifier) { e->setDropAction(Qt::MoveAction); | ||
e->accept(); | e->accept(); | ||
} else if (e->proposedAction() == Qt::MoveAction) | } else if (e->proposedAction() == Qt::MoveAction) | ||
e->acceptProposedAction(); | e->acceptProposedAction(); | ||
} | } | ||
void dropEvent(QDropEvent *e) | void dropEvent(QDropEvent *e) | ||
{ | { | ||
if (e->keyboardModifiers() == Qt::NoModifier) { | if (e->keyboardModifiers() == Qt::NoModifier) { | ||
QListWidget::dropEvent(e); | QListWidget::dropEvent(e); | ||
e->setDropAction(Qt::MoveAction); | e->setDropAction(Qt::MoveAction); | ||
e->accept(); | e->accept(); | ||
} else if (e->proposedAction() == Qt::MoveAction) { | } else if (e->proposedAction() == Qt::MoveAction) { | ||
QListWidget::dropEvent(e); | QListWidget::dropEvent(e); | ||
e->acceptProposedAction(); | e->acceptProposedAction(); | ||
} else | } else | ||
QListWidget::dropEvent(e); | QListWidget::dropEvent(e); | ||
} | } | ||
}; | }; | ||
#include "main.moc" | #include "main.moc" | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
QWidget wid; | QWidget wid; | ||
ListWidget *box = new ListWidget; | ListWidget *box = new ListWidget; | ||
ListWidget *box2 = new ListWidget | ListWidget *box2 = new ListWidget | ||
QVBoxLayout layout(&wid); | QVBoxLayout layout(&wid); | ||
layout.addWidget(box); | layout.addWidget(box); | ||
layout.addWidget(box2); | layout.addWidget(box2); | ||
wid.show(); | wid.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I get rid of the sizegrip of a window on Mac OS X?=== | ===How can I get rid of the sizegrip of a window on Mac OS X?=== | ||
Qt/Mac uses the sizegrip given from Mac OS X. When calling | Qt/Mac uses the sizegrip given from Mac OS X. When calling | ||
< | <syntaxhighlight lang="cpp">statusBar()->setSizeGripEnabled(true)</syntaxhighlight> | ||
the status bar creates a QSizeGrip http://doc.qt.io/qt-5 | the status bar creates a QSizeGrip http://doc.qt.io/qt-5/qsizegrip.html, hides the native Mac OS X size grip, and places the QSizeGrip in the same location as the native size grip. If you don't want any sizegrip to appear, then you need to give your window a fixed size. If you don't want to give your window a fixed size, then you can use the QSizeGrip provided by Qt and call setFixedSize(0,0) on that one, e.g: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
Line 5,640: | Line 5,470: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How do I add a custom Info.plist to my Mac application with qmake?=== | ===How do I add a custom Info.plist to my Mac application with qmake?=== | ||
You can set your own Info.plist by setting the QMAKE_INFO_PLIST variable to your Info.plist file. qmake will add a rule in the Makefile it generates to copy this over. If you don't specify this, qmake provides a generic Info.plist file. | You can set your own Info.plist by setting the QMAKE_INFO_PLIST variable to your Info.plist file. qmake will add a rule in the Makefile it generates to copy this over. If you don't specify this, qmake provides a generic Info.plist file. | ||
< | <syntaxhighlight>QMAKE_INFO_PLIST = MyInfo.plist # qmake will copy this file to MyApp.app/Contents/Info.plist</syntaxhighlight> | ||
===How often will new Qt SDK packages be released?=== | ===How often will new Qt SDK packages be released?=== | ||
A new SDK package will be released each time a new Qt version is released, or | A new SDK package will be released each time a new Qt version is released, or | ||
when a new minor version (1.x) of Qt Creator is released. | when a new minor version (1.x) of Qt Creator is released. | ||
===Why is it only possible to draw in the GUI thread and how can this be worked around?=== | ===Why is it only possible to draw in the GUI thread and how can this be worked around?=== | ||
X11 does rendering in a single thread so even if you use different threads to draw, the drawing will be serialized in the X server thread, so there is no benefit from drawing in different threads. | X11 does rendering in a single thread so even if you use different threads to draw, the drawing will be serialized in the X server thread, so there is no benefit from drawing in different threads. | ||
On Windows the same is true. Since Qt normally relies on the underlying Windowing System, we don't provide this option. However, we do provide the option to render into a QImage from a Non-GUI thread, as this is a pure software solution only partially relying on the underlying system. It is also possible to do multi-threaded text layout and printing, see: | On Windows the same is true. Since Qt normally relies on the underlying Windowing System, we don't provide this option. However, we do provide the option to render into a QImage from a Non-GUI thread, as this is a pure software solution only partially relying on the underlying system. It is also possible to do multi-threaded text layout and printing, see: | ||
Line 5,664: | Line 5,494: | ||
According to our measurements, you can on a desktop computer draw approximately 500 000 triangles (10*10 pixels) per second. | According to our measurements, you can on a desktop computer draw approximately 500 000 triangles (10*10 pixels) per second. | ||
===How can I make the text of a disabled widget look enabled?=== | ===How can I make the text of a disabled widget look enabled?=== | ||
In order to make the text of a disabled widget look enabled, you can change the color of the disabled colorgroup in the palette to have the same color as the active color group. See the documentation on QPalette::setColor() http://doc.qt.io/qt-5/qpalette.html#setColor | In order to make the text of a disabled widget look enabled, you can change the color of the disabled colorgroup in the palette to have the same color as the active color group. See the documentation on QPalette::setColor() http://doc.qt.io/qt-5/qpalette.html#setColor | ||
The following example demonstrates how this can be done for a QLineEdit http://doc.qt.io/qt-5 | The following example demonstrates how this can be done for a QLineEdit http://doc.qt.io/qt-5/qlineedit.html: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
QLineEdit edit; | QLineEdit edit; | ||
edit.setText("Lineedit"); | edit.setText("Lineedit"); | ||
edit.setDisabled(true); | edit.setDisabled(true); | ||
QPalette pal = edit.palette(); | QPalette pal = edit.palette(); | ||
pal.setColor(QPalette::Disabled, QPalette::Text, pal.color(QPalette::Active, QPalette::Text)); | pal.setColor(QPalette::Disabled, QPalette::Text, pal.color(QPalette::Active, QPalette::Text)); | ||
pal.setColor(QPalette::Disabled, QPalette::Base, pal.color(QPalette::Active, QPalette::Base)); | pal.setColor(QPalette::Disabled, QPalette::Base, pal.color(QPalette::Active, QPalette::Base)); | ||
edit.setPalette(pal); | edit.setPalette(pal); | ||
edit.show(); | edit.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Why do you provide container classes as an alternative to STL in Qt?=== | ===Why do you provide container classes as an alternative to STL in Qt?=== | ||
We want our container classes to behave in the same way on all platforms. The different compilers might have different implementations of STL, so the behavior can vary. In addition when we created the container classes, not all platforms had decent implementations of STL. Finally, we provide QString http://doc.qt.io/qt-5 | We want our container classes to behave in the same way on all platforms. The different compilers might have different implementations of STL, so the behavior can vary. In addition when we created the container classes, not all platforms had decent implementations of STL. Finally, we provide QString http://doc.qt.io/qt-5/qstring.html which is a string class which provides a string of unicode characters. Since QString is available on all platforms, we can be sure that it will work for passing unicode characters from one place to another. | ||
===How do I create a default size for the rows in a table view?=== | ===How do I create a default size for the rows in a table view?=== | ||
Line 5,699: | Line 5,529: | ||
The example below demonstrates how this can be achieved | The example below demonstrates how this can be achieved | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Model : public QAbstractTableModel | class Model : public QAbstractTableModel | ||
{ | { | ||
public: | public: | ||
Model(QObject *parent) | Model(QObject *parent) | ||
{ | { | ||
QStringList firstRow; | QStringList firstRow; | ||
Line 5,736: | Line 5,566: | ||
// Any valid index that corresponds to a string for the index's column and row in | // Any valid index that corresponds to a string for the index's column and row in | ||
// the stringlist is returned | // the stringlist is returned | ||
QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const | QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const | ||
{ | { | ||
if (!index.isValid()) | if (!index.isValid()) | ||
Line 5,743: | Line 5,573: | ||
return QVariant(); | return QVariant(); | ||
QStringList list = (QStringList)stringList.at(index.row()); | QStringList list = (QStringList)stringList.at(index.row()); | ||
return list.at(index.column()); | return list.at(index.column()); | ||
} | } | ||
private: | private: | ||
Line 5,772: | Line 5,602: | ||
tableView->setModel(model); | tableView->setModel(model); | ||
for (int i = 0; i < model->rowCount(); i++) { | for (int i = 0; i < model->rowCount(); i++) { | ||
tableView->resizeRowToContents(i); | tableView->resizeRowToContents(i); | ||
} | } | ||
Line 5,778: | Line 5,608: | ||
widget.show(); | widget.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I embed e.g a QMainWindow inside a QDialog ?=== | ===How can I embed e.g a QMainWindow inside a QDialog ?=== | ||
In order to embed a toplevel window inside another window you need to create the embedded window without a parent and then call setParent() http://doc.qt.io/qt-5 | In order to embed a toplevel window inside another window you need to create the embedded window without a parent and then call setParent() http://doc.qt.io/qt-5/qwidget.html#setParent on it after the embedded window has been constructed. | ||
See the following example for an illustration: | See the following example for an illustration: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
Line 5,810: | Line 5,640: | ||
return box.exec(); | return box.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How do I set the width or height of the header sections in a view?=== | ===How do I set the width or height of the header sections in a view?=== | ||
You can set the width or height of the header sections in a view by calling QHeaderView::resizeSection() http://doc.qt.io/qt-5 | You can set the width or height of the header sections in a view by calling QHeaderView::resizeSection() http://doc.qt.io/qt-5/qheaderview.html#resizeSection. The QHeaderView class provides a header row or header column for item views, and you can use the header() http://doc.qt.io/qt-5/qtreeview.html#header, horizontalHeader() http://doc.qt.io/qt-5/qtableview.html#horizontalHeader or verticalHeader() http://doc.qt.io/qt-5/qtableview.html#verticalHeader (depending on what your view is) functions to access them. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include <QApplication> | #include <QApplication> | ||
#include <QTableWidget> | #include <QTableWidget> | ||
Line 5,825: | Line 5,655: | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
QTableWidget table(2,2); | QTableWidget table(2,2); | ||
QTableWidgetItem *itemOne = new QTableWidgetItem("one"); | QTableWidgetItem *itemOne = new QTableWidgetItem("one"); | ||
table.setItem(0,0,itemOne); | table.setItem(0,0,itemOne); | ||
Line 5,831: | Line 5,661: | ||
table.horizontalHeader()->resizeSection(0, 200); | table.horizontalHeader()->resizeSection(0, 200); | ||
table.verticalHeader()->resizeSection(1, 200); | table.verticalHeader()->resizeSection(1, 200); | ||
table.show(); | table.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I sort the items in a QTableWidget on multiple columns?=== | ===How can I sort the items in a QTableWidget on multiple columns?=== | ||
Line 5,848: | Line 5,678: | ||
will more efficiently sort based on multiple columns. | will more efficiently sort based on multiple columns. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
#define SETPERSON(index, first, second, salary) setItem(index, 0, new QTableWidgetItem(first)); | #define SETPERSON(index, first, second, salary) setItem(index, 0, new QTableWidgetItem(first)); | ||
setItem(index, 1, new QTableWidgetItem(second)); | setItem(index, 1, new QTableWidgetItem(second)); | ||
setItem(index, 2, new QTableWidgetItem); | setItem(index, 2, new QTableWidgetItem); | ||
item(index, 2)->setData(Qt::DisplayRole, salary); | item(index, 2)->setData(Qt::DisplayRole, salary); | ||
Line 5,860: | Line 5,690: | ||
Q_OBJECT | Q_OBJECT | ||
public: | public: | ||
Table(QWidget *parent = | Table(QWidget *parent = nullptr) | ||
: QTableWidget(6, 3, parent) | : QTableWidget(6, 3, parent) | ||
{ | { | ||
Line 5,935: | Line 5,765: | ||
return a.exec(); | return a.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I translate the application menu on the Mac?=== | ===How can I translate the application menu on the Mac?=== | ||
Line 5,947: | Line 5,777: | ||
You can take a look at the contents of many of your applications installed in /Applications. They should be similar to what's described here. | You can take a look at the contents of many of your applications installed in /Applications. They should be similar to what's described here. | ||
===When popping up a context menu, how can I get hold of the cell where the menu popped up in my view?=== | ===When popping up a context menu, how can I get hold of the cell where the menu popped up in my view?=== | ||
When reimplementing the contextMenuEvent() http://doc.qt.io/qt-5 | When reimplementing the contextMenuEvent() http://doc.qt.io/qt-5/qabstractscrollarea.html#contextMenuEvent in a view to pop up a menu where the cursor is located, then you can pass in the cursor's global position as an argument to exec() http://doc.qt.io/qt-5/qmenu.html#exec. For determining which cell was clicked then simply use the event's pos() http://doc.qt.io/qt-5/qcontextmenuevent.html#pos value as an argument to indexAt() http://doc.qt.io/qt-5/qtableview.html#indexAt and get the QModelIndex that way. | ||
The example below demonstrates how this can be done for a QTableView: | The example below demonstrates how this can be done for a QTableView: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Model : public QAbstractTableModel | class Model : public QAbstractTableModel | ||
Line 5,970: | Line 5,800: | ||
stringList << firstRow << secondRow; | stringList << firstRow << secondRow; | ||
} | } | ||
int rowCount ( const QModelIndex & parent = QModelIndex() ) const | int rowCount ( const QModelIndex & parent = QModelIndex() ) const | ||
{ | { | ||
return stringList.count(); | return stringList.count(); | ||
} | } | ||
int columnCount ( const QModelIndex & parent = QModelIndex() ) const | int columnCount ( const QModelIndex & parent = QModelIndex() ) const | ||
{ | { | ||
return stringList[0].count(); | return stringList[0].count(); | ||
} | } | ||
QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const | QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const | ||
{ | { | ||
if (!index.isValid()) | if (!index.isValid()) | ||
Line 5,988: | Line 5,818: | ||
return QVariant(); | return QVariant(); | ||
QStringList list = (QStringList)stringList.at(index.row()); | QStringList list = (QStringList)stringList.at(index.row()); | ||
return list.at(index.column()); | return list.at(index.column()); | ||
} | } | ||
private: | private: | ||
QList<QStringList>stringList; | QList<QStringList>stringList; | ||
}; | }; | ||
Line 6,000: | Line 5,830: | ||
TableView(QWidget *parent) : QTableView(parent) | TableView(QWidget *parent) : QTableView(parent) | ||
{} | {} | ||
void contextMenuEvent ( QContextMenuEvent * e ) | void contextMenuEvent ( QContextMenuEvent * e ) | ||
{ | { | ||
Line 6,018: | Line 5,848: | ||
QWidget widget; | QWidget widget; | ||
QHBoxLayout *layout = new QHBoxLayout(&widget); | QHBoxLayout *layout = new QHBoxLayout(&widget); | ||
TableView *tableView = new TableView(&widget); | TableView *tableView = new TableView(&widget); | ||
Model *model = new Model(tableView); | Model *model = new Model(tableView); | ||
tableView->setModel(model); | tableView->setModel(model); | ||
layout->addWidget(tableView); | layout->addWidget(tableView); | ||
widget.show(); | widget.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Intellisense does not work for my Qt application. What's wrong?=== | ===Intellisense does not work for my Qt application. What's wrong?=== | ||
Line 6,044: | Line 5,874: | ||
public slots:; | public slots:; | ||
< | <syntaxhighlight lang="cpp"> | ||
void mySlot(); | void mySlot(); | ||
</ | </syntaxhighlight> | ||
2. The class/struct is not directly included. Sometimes the completion on e.g. | 2. The class/struct is not directly included. Sometimes the completion on e.g. | ||
a push button object does not work since you included <QtGui>. For compilation | a push button object does not work since you included <QtGui>. For compilation | ||
Line 6,071: | Line 5,901: | ||
regenerated when the project is opened and built, respectively, and could help | regenerated when the project is opened and built, respectively, and could help | ||
if the problem is due to some sort of corruption in those files. | if the problem is due to some sort of corruption in those files. | ||
===Is it possible to reimplement non-virtual slots?=== | ===Is it possible to reimplement non-virtual slots?=== | ||
Line 6,081: | Line 5,911: | ||
setting it up in a slot connected to a single shot timer. | setting it up in a slot connected to a single shot timer. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class TableWidget : public QTableWidget | class TableWidget : public QTableWidget | ||
Line 6,092: | Line 5,922: | ||
QTimer::singleShot(0, this, SLOT(fixHeader())); | QTimer::singleShot(0, this, SLOT(fixHeader())); | ||
} | } | ||
public slots: | public slots: | ||
void fixHeader() | void fixHeader() | ||
Line 6,103: | Line 5,933: | ||
} | } | ||
protected slots: | protected slots: | ||
void columnResized(int a, int b, int col) | void columnResized(int a, int b, int col) | ||
{ | { | ||
qDebug() << "This is called"; | qDebug() << "This is called"; | ||
} | } | ||
}; | }; | ||
Line 6,116: | Line 5,946: | ||
TableWidget box; | TableWidget box; | ||
box.show(); | box.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===When running on Linux then Eclipse crashes frequently. The 'problematic frame' seems to be 'gtk_tooltips_set_tip+0x1dc'. What is the problem ?=== | ===When running on Linux then Eclipse crashes frequently. The 'problematic frame' seems to be 'gtk_tooltips_set_tip+0x1dc'. What is the problem ?=== | ||
Line 6,126: | Line 5,956: | ||
https://bugs.launchpad.net/ubuntu/+source/eclipse/+bug/128232 | https://bugs.launchpad.net/ubuntu/+source/eclipse/+bug/128232 | ||
===Does Qt for Embedded Linux support mouse shortcuts?=== | ===Does Qt for Embedded Linux support mouse shortcuts?=== | ||
Yes. The following shortcuts are supported: | Yes. The following shortcuts are supported: | ||
* double-click the title bar | * double-click the title bar | ||
Line 6,137: | Line 5,967: | ||
* click-n-drag to select text | * click-n-drag to select text | ||
* double-click to select a word of text | * double-click to select a word of text | ||
===How can I make a QComboBox have multiple selection?=== | ===How can I make a QComboBox have multiple selection?=== | ||
With the example given below, you can currently do multiple selection by dragging the mouse over the items you want to select. There is only one thing left that needs to be done, and that's to decide how you want to make the combobox's popup disappear. This is not illustrated in the example, but all you need to do is install an event filter on the view for the combobox and when you get a mouse button release, you can either eat the event or let it carry on. Eating it would prevent it from closing the popup and therefore allow you to close it when you want. As long as you call hidePopup() http://doc.qt.io/qt-5/qcombobox.html#hidePopup when you want it to be closed, then it will ensure that everything is updated as appropriate. | With the example given below, you can currently do multiple selection by dragging the mouse over the items you want to select. There is only one thing left that needs to be done, and that's to decide how you want to make the combobox's popup disappear. This is not illustrated in the example, but all you need to do is install an event filter on the view for the combobox and when you get a mouse button release, you can either eat the event or let it carry on. Eating it would prevent it from closing the popup and therefore allow you to close it when you want. As long as you call hidePopup() http://doc.qt.io/qt-5/qcombobox.html#hidePopup when you want it to be closed, then it will ensure that everything is updated as appropriate. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class MyComboBox : public QComboBox | class MyComboBox : public QComboBox | ||
Line 6,149: | Line 5,979: | ||
Q_OBJECT | Q_OBJECT | ||
public: | public: | ||
MyComboBox(QWidget *parent = | MyComboBox(QWidget *parent = nullptr) : QComboBox(parent) | ||
{ | { | ||
addItem("A"); | addItem("A"); | ||
Line 6,164: | Line 5,994: | ||
QAbstractItemModel *model = view()->model(); | QAbstractItemModel *model = view()->model(); | ||
for (int i=0;i<strs.size();++i) { | for (int i=0;i<strs.size();++i) { | ||
QModelIndexList idxes = model->match(model->index(0, 0), Qt::DisplayRole, strs.at(i), 1, | QModelIndexList idxes = model->match(model->index(0, 0), Qt::DisplayRole, strs.at(i), 1, | ||
Qt::MatchExactly); | Qt::MatchExactly); | ||
foreach(QModelIndex idx, idxes) | foreach(QModelIndex idx, idxes) | ||
Line 6,198: | Line 6,028: | ||
return a.exec(); | return a.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I draw vertical text?=== | ===How can I draw vertical text?=== | ||
Drawing vertical text can be done in several ways. The easiest way might be to create a QTextDocument http://doc.qt.io/qt-5 | Drawing vertical text can be done in several ways. The easiest way might be to create a QTextDocument http://doc.qt.io/qt-5/qtextdocument.html in the paintEvent() http://doc.qt.io/qt-5/qwidget.html#paintEvent and use setHtml() http://doc.qt.io/qt-5/qtextdocument.html#setHtml to set the text and specify the | ||
< | <nowiki><br/></nowiki> | ||
tag to get line breaks. Another way could be to iterate over the QChars http://doc.qt.io/qt-5 | tag to get line breaks. Another way could be to iterate over the QChars http://doc.qt.io/qt-5/qchar.html in the QString http://doc.qt.io/qt-5/qstring.html and position them vertically in the paintEvent() yourself. Then you would need to calculate the height between each element. | ||
If what you want is rotated text, then you can simply rotate the painter 90 degrees. | If what you want is rotated text, then you can simply rotate the painter 90 degrees. | ||
Finally, if you are not going to draw the text yourself, then a QLabel http://doc.qt.io/qt-5 | Finally, if you are not going to draw the text yourself, then a QLabel http://doc.qt.io/qt-5/qlabel.html can easily be used to display vertical text, simply by specifying \n after each character. | ||
The example below illustrates some of the possibilities: | The example below illustrates some of the possibilities: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Widget : public QWidget | class Widget : public QWidget | ||
{ | { | ||
public: | public: | ||
Widget(QWidget *parent = | Widget(QWidget *parent = nullptr) | ||
: QWidget(parent) | : QWidget(parent) | ||
{} | {} | ||
Line 6,227: | Line 6,057: | ||
{ | { | ||
QPainter p(this); | QPainter p(this); | ||
#if 1 | #if 1 | ||
QTextDocument document; | QTextDocument document; | ||
document.setHtml("<br>T<br>e<br>s<br>t<br>"); | document.setHtml("<br>T<br>e<br>s<br>t<br>"); | ||
document.drawContents(&p); | document.drawContents(&p); | ||
#else | #else | ||
drawRotatedText(&p, 90, width() / 2, height() / 2, "The vertical text"); | drawRotatedText(&p, 90, width() / 2, height() / 2, "The vertical text"); | ||
#endif | #endif | ||
Line 6,257: | Line 6,087: | ||
return a.exec(); | return a.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===I would like to detect if the expansion sign has been clicked in my QTreeView. How can this be achieved?=== | ===I would like to detect if the expansion sign has been clicked in my QTreeView. How can this be achieved?=== | ||
If you want to be notified when the user clicks the expansion button for the items in your tree, then you can reimplement the mousePressEvent() http://doc.qt.io/qt-5 | If you want to be notified when the user clicks the expansion button for the items in your tree, then you can reimplement the mousePressEvent() http://doc.qt.io/qt-5/qtreeview.html#mousePressEvent and calculate the position of the expansion sign. If the mouse is over the calculated position, then you can for example emit a signal to notify it and do your own handling. Otherwise, simply call the base implementation. | ||
The following example demonstrates how this can be done: | The following example demonstrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class TreeWidget : public QTreeWidget | class TreeWidget : public QTreeWidget | ||
Line 6,277: | Line 6,107: | ||
item1->setText(0, "item 1"); | item1->setText(0, "item 1"); | ||
item1->setExpanded(true); | item1->setExpanded(true); | ||
item2 = new QTreeWidgetItem(item1); | item2 = new QTreeWidgetItem(item1); | ||
item2->setText(0, "item 2"); | item2->setText(0, "item 2"); | ||
Line 6,293: | Line 6,123: | ||
QRect vrect = visualRect(indexClicked); | QRect vrect = visualRect(indexClicked); | ||
int itemIndentation = vrect.x() - visualRect(rootIndex()).x(); | int itemIndentation = vrect.x() - visualRect(rootIndex()).x(); | ||
QRect rect = QRect(header()->sectionViewportPosition(0) + itemIndentation - | QRect rect = QRect(header()->sectionViewportPosition(0) + itemIndentation - | ||
indentation(), vrect.y(), indentation(), vrect.height()); | indentation(), vrect.y(), indentation(), vrect.height()); | ||
if(rect.contains(event->pos()) && model()->hasChildren(indexClicked)) { | if(rect.contains(event->pos()) && model()->hasChildren(indexClicked)) { | ||
qDebug() << "plus clicked"; | qDebug() << "plus clicked"; | ||
Line 6,318: | Line 6,148: | ||
TreeWidget box; | TreeWidget box; | ||
box.show(); | box.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I catch Alt+F4 in my Qt application ?=== | ===How can I catch Alt+F4 in my Qt application ?=== | ||
Alt+F4 is a key combination controlled by Windows and Qt has no control over such system keys. What you can try to get around this is to start a QTimer to calculate the time from when Alt is pressed until the widget receives a closeEvent() http://doc.qt.io/qt-5/qwidget.html#closeEvent. If the closeEvent() http://doc.qt.io/qt-5/qwidget.html#closeEvent is received before e.g 300 msecs have passed, you can assume that Alt+F4 was pressed. See the following example for an illustration: | Alt+F4 is a key combination controlled by Windows and Qt has no control over such system keys. What you can try to get around this is to start a QTimer to calculate the time from when Alt is pressed until the widget receives a closeEvent() http://doc.qt.io/qt-5/qwidget.html#closeEvent. If the closeEvent() http://doc.qt.io/qt-5/qwidget.html#closeEvent is received before e.g 300 msecs have passed, you can assume that Alt+F4 was pressed. See the following example for an illustration: | ||
< | <syntaxhighlight lang="cpp">#include <QtWidgets> | ||
class MainWindow : public QMainWindow | class MainWindow : public QMainWindow | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
MainWindow() : QMainWindow() | |||
{ | |||
altPressed = false; | |||
installEventFilter(this); | |||
} | |||
void closeEvent(QCloseEvent *event) | |||
{ | |||
if (altPressed) { | |||
qDebug() << Alt + f4 was pressed, causing shutdown; | |||
} else { | |||
qDebug() << Alt + f4 was not pressed. Shutting down for another reason; | |||
} | |||
QMainWindow::closeEvent(event); | QMainWindow::closeEvent(event); | ||
} | } | ||
bool eventFilter(QObject *o, QEvent *e) | |||
{ | |||
if (e->type() == QEvent::ShortcutOverride) { | |||
QKeyEvent *event = (QKeyEvent *)e; | |||
if(event->modifiers() == Qt::AltModifier) { | |||
altPressed = true; | |||
QTimer::singleShot(300, this, SLOT(testSlot())); | |||
return false; | |||
} | |||
} | |||
return QMainWindow::event(e); | |||
} | |||
public slots: | |||
void testSlot() | |||
{ | |||
qDebug() << Only Alt was pressed; | |||
altPressed = false; | |||
} | |||
private: | private: | ||
bool altPressed; | |||
}; | }; | ||
Line 6,372: | Line 6,202: | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
MainWindow main; | |||
main.show(); | |||
return app.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
===When running a Qt application on the French translation of Mac OS X, About shows up instead of A propos in the application menu. What is wrong ?=== | ===When running a Qt application on the French translation of Mac OS X, About shows up instead of A propos in the application menu. What is wrong ?=== | ||
The reason why About shows up instead of A propos in this situation is that the About text is set by Qt. Preferences, Quit, etc are given the standard Carbon commands, so Carbon can detect which language to display them in provided that you have the correct .lproj in your application bundle. Since there is no general way to translate the About text, you can provide the text you want by subclassing QTranslator http://doc.qt.io/qt-5 | The reason why About shows up instead of A propos in this situation is that the About text is set by Qt. Preferences, Quit, etc are given the standard Carbon commands, so Carbon can detect which language to display them in provided that you have the correct .lproj in your application bundle. Since there is no general way to translate the About text, you can provide the text you want by subclassing QTranslator http://doc.qt.io/qt-5/qtranslator.html and reimplementing translate() http://doc.qt.io/qt-5/qtranslator.html#translate to return the text you want. | ||
See the following example for an illustration: | See the following example for an illustration: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Translator : public QTranslator | class Translator : public QTranslator | ||
{ | { | ||
Q_OBJECT | Q_OBJECT | ||
public: | public: | ||
Translator(QWidget* parent=0) : QTranslator(parent) {} | Translator(QWidget* parent=0) : QTranslator(parent) {} | ||
QString translate(const char *context, const char *sourceText, | QString translate(const char *context, const char *sourceText, | ||
const char *comment = | const char *comment = nullptr) const | ||
{ | { | ||
if (QString(context).compare("QMenuBar") == 0 && | if (QString(context).compare("QMenuBar") == 0 && | ||
QString(sourceText).compare("About %1") == 0) { | QString(sourceText).compare("About %1") == 0) { | ||
return QString("Apropos d' %1"); | return QString("Apropos d' %1"); | ||
} | } | ||
return sourceText; | return sourceText; | ||
} | } | ||
}; | }; | ||
#include "main.moc" | #include "main.moc" | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
Translator translator; | Translator translator; | ||
app.installTranslator(&translator); | app.installTranslator(&translator); | ||
QMainWindow window; | QMainWindow window; | ||
QMenu *menu = window.menuBar()->addMenu("Test"); | QMenu *menu = window.menuBar()->addMenu("Test"); | ||
QAction *firstAction = menu->addAction(QObject::tr("Random text")); | QAction *firstAction = menu->addAction(QObject::tr("Random text")); | ||
firstAction->setMenuRole(QAction::AboutRole); | firstAction->setMenuRole(QAction::AboutRole); | ||
QAction *secondAction = menu->addAction(QObject::tr("Preferences")); | QAction *secondAction = menu->addAction(QObject::tr("Preferences")); | ||
secondAction->setMenuRole(QAction::PreferencesRole); | secondAction->setMenuRole(QAction::PreferencesRole); | ||
window.show(); | window.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I have a partially transparent pixmap on my toplevel window?=== | ===How can I have a partially transparent pixmap on my toplevel window?=== | ||
Line 6,425: | Line 6,255: | ||
# Extract the transparent areas from the image as a bitmap and set this as the widget mask. This will not allow you to have partially transparent areas. | # Extract the transparent areas from the image as a bitmap and set this as the widget mask. This will not allow you to have partially transparent areas. | ||
# If you want to show a QPixmap http://doc.qt.io/qt-5 | # If you want to show a QPixmap http://doc.qt.io/qt-5/qpixmap.html with an alpha as your splash screen, then you | ||
can use this approach which is slightly less efficient. You need to figure out the geometry of your splashscreen and use QPixmap::grabWindow() http://doc.qt.io/qt-5 | can use this approach which is slightly less efficient. You need to figure out the geometry of your splashscreen and use QPixmap::grabWindow() http://doc.qt.io/qt-5/qpixmap.html#grabWindow to fetch this area into a QPixmap. Then take your pixmap and blend it on top of the grabbed pixmap. The resulting pixmap you can set as the widget pixmap. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Widget : public QWidget | class Widget : public QWidget | ||
Line 6,465: | Line 6,295: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I do multiselection in a QCalendarWidget?=== | ===How can I do multiselection in a QCalendarWidget?=== | ||
There is no direct API for doing multi selection in a QCalendarWidget http://doc.qt.io/qt-5 | There is no direct API for doing multi selection in a QCalendarWidget http://doc.qt.io/qt-5/qcalendarwidget.html. What you can do however is to install an event filter on the viewport of the QTableView http://doc.qt.io/qt-5/qtableview.html which is used by the QCalendarWidget and check to see if the Shift modifier is pressed and if so select the relevant QModelIndexes http://doc.qt.io/qt-5/qmodelindex.html. The example below demonstrates how this can be done. Note that the example will need some tweaking if you want to use it. It does for example only work when selecting forwards, not when selecting backwards. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class CalendarWidget : public QCalendarWidget { | class CalendarWidget : public QCalendarWidget { | ||
Q_OBJECT | Q_OBJECT | ||
public: | public: | ||
CalendarWidget(QWidget *parent = | CalendarWidget(QWidget *parent = nullptr) : QCalendarWidget(parent) | ||
{ | { | ||
view = qFindChild<QTableView *>(this); | view = qFindChild<QTableView *>(this); | ||
Line 6,495: | Line 6,325: | ||
if (idx.row() != 0 && idx.column() != 0) | if (idx.row() != 0 && idx.column() != 0) | ||
startIndex = idx; | startIndex = idx; | ||
} else if (event->type() == QEvent::MouseButtonRelease && | } else if (event->type() == QEvent::MouseButtonRelease && | ||
me->modifiers() & Qt::ShiftModifier) { | me->modifiers() & Qt::ShiftModifier) { | ||
QModelIndex idx = view->indexAt(pos); | QModelIndex idx = view->indexAt(pos); | ||
Line 6,503: | Line 6,333: | ||
return false; | return false; | ||
if (!startIndex.isValid()) | if (!startIndex.isValid()) | ||
startIndex = | startIndex = | ||
view->selectionModel()->selectedIndexes().first(); | view->selectionModel()->selectedIndexes().first(); | ||
endIndex = view->indexAt(pos); | endIndex = view->indexAt(pos); | ||
Line 6,557: | Line 6,387: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Is it possible to install and run Qt for Embedded Linux on a headless machine?=== | ===Is it possible to install and run Qt for Embedded Linux on a headless machine?=== | ||
Yes. Remote display is possible by using Qt for Embedded Linux's VNC drivers. | Yes. Remote display is possible by using Qt for Embedded Linux's VNC drivers. | ||
===Does Qt for Embedded Linux support keyboard navigation?=== | ===Does Qt for Embedded Linux support keyboard navigation?=== | ||
Yes. Qt for Embedded Linux supports the following: | Yes. Qt for Embedded Linux supports the following: | ||
* Tab groups | * Tab groups | ||
Line 6,577: | Line 6,407: | ||
* Windows-key-D (minimize all windows) | * Windows-key-D (minimize all windows) | ||
* Esc (remove dialog or menu) | * Esc (remove dialog or menu) | ||
===Does the Qt for Embedded Linux windowing system support standard window operations?=== | ===Does the Qt for Embedded Linux windowing system support standard window operations?=== | ||
Line 6,588: | Line 6,418: | ||
* reposition by click-n-drag | * reposition by click-n-drag | ||
* select the active window by clicking on it | * select the active window by clicking on it | ||
===How does Qt for Embedded Linux access the display?=== | ===How does Qt for Embedded Linux access the display?=== | ||
Qt for Embedded Linux comes with some graphics drivers, but most of Qt for Embedded Linux applications access the Linux video frame buffer directly. Specific accelerated drivers can also be implemented in Qt for Embedded Linux, as plug-in, to improve performances. Such drivers access the graphics hardware directly to utilize any available hardware acceleration of graphics operations. | Qt for Embedded Linux comes with some graphics drivers, but most of Qt for Embedded Linux applications access the Linux video frame buffer directly. Specific accelerated drivers can also be implemented in Qt for Embedded Linux, as plug-in, to improve performances. Such drivers access the graphics hardware directly to utilize any available hardware acceleration of graphics operations. | ||
===Why can't I debug the Qt sources when using the Qt SDK?=== | ===Why can't I debug the Qt sources when using the Qt SDK?=== | ||
Line 6,599: | Line 6,429: | ||
Qt for Embedded Linux has a plug-in framework for mouse and keyboard drivers. Some | Qt for Embedded Linux has a plug-in framework for mouse and keyboard drivers. Some | ||
drivers are already supported (linuxtp, intellimouse, mouseman, tslib etc.). Individual drivers can easily be written. Qt for Embedded Linux can also connect to kernel drivers for mouse and keyboard over sockets. | drivers are already supported (linuxtp, intellimouse, mouseman, tslib etc.). Individual drivers can easily be written. Qt for Embedded Linux can also connect to kernel drivers for mouse and keyboard over sockets. | ||
===How can I change the row height of a QTreeView?=== | ===How can I change the row height of a QTreeView?=== | ||
The delegate's sizeHint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#sizeHint is used to determine the row height of the QTreeView, so you need to reimplement the delegate's sizeHint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#sizeHint to return the size you want. | The delegate's sizeHint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#sizeHint is used to determine the row height of the QTreeView, so you need to reimplement the delegate's sizeHint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#sizeHint to return the size you want. | ||
The following example illustrates how this can be done: | The following example illustrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class ItemDelegate : public | class ItemDelegate : public QStyledItemDelegate | ||
{ | { | ||
public: | public: | ||
using QStyledItemDelegate::QStyledItemDelegate; | |||
QSize sizeHint (const QStyleOptionViewItem &option, const QModelIndex &index) const override | |||
QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const | |||
{ | { | ||
return QSize(50,50); | return QSize(50, 50); | ||
} | } | ||
}; | }; | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
Line 6,632: | Line 6,462: | ||
}} | }} | ||
ItemDelegate *delegate = new ItemDelegate(); | ItemDelegate *delegate = new ItemDelegate(); | ||
view.setModel(model); | view.setModel(model); | ||
view.setItemDelegate(delegate); | view.setItemDelegate(delegate); | ||
view.show(); | view.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I avoid the underlining of links in a QTextBrowser ?=== | ===How can I avoid the underlining of links in a QTextBrowser ?=== | ||
You can use style sheets for that. Here is an example: | You can use style sheets for that. Here is an example: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
Line 6,659: | Line 6,489: | ||
} | } | ||
</ | </syntaxhighlight> | ||
If you start this example with 'index.html' taken from the Qt documentation | If you start this example with 'index.html' taken from the Qt documentation | ||
all the links will have their underline removed (no text decoration) and the | all the links will have their underline removed (no text decoration) and the | ||
Line 6,669: | Line 6,499: | ||
for the list of supported CSS selectors. | for the list of supported CSS selectors. | ||
===Is it possible with Qt for Embedded Linux to maximize a window to full screen mode without any toolbars, scrollbars, menubars and the like?=== | ===Is it possible with Qt for Embedded Linux to maximize a window to full screen mode without any toolbars, scrollbars, menubars and the like?=== | ||
Yes. This can this be done with Qt for Embedded Linux. It is also possible to expose a hidden toolbar at the top of the screen as one typically sees in these fullscreen modes. | Yes. This can this be done with Qt for Embedded Linux. It is also possible to expose a hidden toolbar at the top of the screen as one typically sees in these fullscreen modes. | ||
===What kind of touch screen / touch panel support does Qt for Embedded Linux have?=== | ===What kind of touch screen / touch panel support does Qt for Embedded Linux have?=== | ||
Line 6,681: | Line 6,511: | ||
Panel and tslib. Qt for Embedded Linux has a touch screen driver plug-in framework for | Panel and tslib. Qt for Embedded Linux has a touch screen driver plug-in framework for | ||
implementing individual drivers. | implementing individual drivers. | ||
===How can I add tooltips to a QComboBox?=== | ===How can I add tooltips to a QComboBox?=== | ||
When setting tooltips for the individual items in a QComboBox http://doc.qt.io/qt-5/qcombobox.html you need to use the setItemData() http://doc.qt.io/qt-5/qcombobox.html#setItemData) function and specify the string you want to use for the tooltip specifying the ToolTipRole as the role for the data. For example: | When setting tooltips for the individual items in a QComboBox http://doc.qt.io/qt-5/qcombobox.html you need to use the setItemData() http://doc.qt.io/qt-5/qcombobox.html#setItemData) function and specify the string you want to use for the tooltip specifying the ToolTipRole as the role for the data. For example: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
Line 6,702: | Line 6,532: | ||
return a.exec(); | return a.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I translate the OK and Cancel buttons when using the static QMessageBox functions?=== | ===How can I translate the OK and Cancel buttons when using the static QMessageBox functions?=== | ||
Line 6,716: | Line 6,546: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
Line 6,728: | Line 6,558: | ||
a.installTranslator(&trans); | a.installTranslator(&trans); | ||
a.installTranslator(&trans2); | a.installTranslator(&trans2); | ||
QMessageBox::warning(0, QObject::tr("Warning Title"), | QMessageBox::warning(0, QObject::tr("Warning Title"), | ||
QObject::tr("Warning Message"), | QObject::tr("Warning Message"), | ||
QMessageBox::Ok|QMessageBox::Cancel); | QMessageBox::Ok|QMessageBox::Cancel); | ||
return a.exec(); | return a.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Why doesn't Mac OS X respect carriage return?=== | ===Why doesn't Mac OS X respect carriage return?=== | ||
On Mac OS X the idea of a new line is the same as on other unices. OS9 and | On Mac OS X the idea of a new line is the same as on other unices. OS9 and | ||
below used carriage return. One decision we made with Qt was to follow the Unix convention on Mac OS X, therefore QTextStream (and Qt in general) does not know how to deal with carriage return. You should use new line instead. | below used carriage return. One decision we made with Qt was to follow the Unix convention on Mac OS X, therefore QTextStream (and Qt in general) does not know how to deal with carriage return. You should use new line instead. | ||
===How can I embed a widget with a titlebar inside a QGraphicsScene?=== | ===How can I embed a widget with a titlebar inside a QGraphicsScene?=== | ||
You can embed a widget with a titlebar inside a QGraphicsScene http://doc.qt.io/qt-5 | You can embed a widget with a titlebar inside a QGraphicsScene http://doc.qt.io/qt-5/qgraphicsscene.html by specifying the Qt::Window http://doc.qt.io/qt-5/qt.html#WindowType-enum flag to the QGraphicsProxyWidget http://doc.qt.io/qt-5/qgraphicsproxywidget.html or the QGraphicsWidget http://doc.qt.io/qt-5/qgraphicswidget.html. | ||
See the following example for an illustration: | See the following example for an illustration: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
Line 6,754: | Line 6,584: | ||
QGraphicsScene scene; | QGraphicsScene scene; | ||
#if 1 | #if 1 | ||
QGraphicsWidget *window = new QGraphicsWidget(0); | QGraphicsWidget *window = new QGraphicsWidget(0); | ||
window->setWindowFlags(Qt::Window); | window->setWindowFlags(Qt::Window); | ||
scene.addItem(window); | scene.addItem(window); | ||
#else | #else | ||
QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget(); | QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget(); | ||
proxy->setWidget(new QMainWindow()); | proxy->setWidget(new QMainWindow()); | ||
Line 6,770: | Line 6,600: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I detect hover events on the tabs of a QTabWidget?=== | ===How can I detect hover events on the tabs of a QTabWidget?=== | ||
The tabs in QTabBar http://doc.qt.io/qt-5 | The tabs in QTabBar http://doc.qt.io/qt-5/qtabbar.html are not widgets per say, so it is not possible to get hold of them to check if they have received any events. Instead, you can check if the position of the event is positioned in the tab by using QTabBar::tabAt() http://doc.qt.io/qt-5/qtabbar.html#tabAt | ||
The following example illustrates how this can be done: | The following example illustrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class TabWidget : public QTabWidget | class TabWidget : public QTabWidget | ||
Line 6,807: | Line 6,637: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Errors using macdeployqt caused by old version of XCode.=== | ===Errors using macdeployqt caused by old version of XCode.=== | ||
If macdeployqt fails with an error containing lines similar to the following : | If macdeployqt fails with an error containing lines similar to the following : | ||
< | <syntaxhighlight>Log: Using install_name_tool: | ||
Log: in calculator.app/Contents/Frameworks/QtGui.framework/Versions/4/QtGui | Log: in calculator.app/Contents/Frameworks/QtGui.framework/Versions/4/QtGui | ||
Log: change reference QtCore.framework/Versions/4/QtCore | Log: change reference QtCore.framework/Versions/4/QtCore | ||
Log: to @executable_path/../Frameworks/QtCore.framework/Versions/4/QtCore | Log: to @executable_path/../Frameworks/QtCore.framework/Versions/4/QtCore | ||
ERROR: install_name_tool: for architecture x86_64 object: calculator.app/Contents/Frameworks/QtGui.framework/Versions/4/QtGui malformed object (unknown load command 5) </ | ERROR: install_name_tool: for architecture x86_64 object: calculator.app/Contents/Frameworks/QtGui.framework/Versions/4/QtGui malformed object (unknown load command 5) </syntaxhighlight> | ||
The reason could be that you are using an older version of XCode. | The reason could be that you are using an older version of XCode. | ||
We have found that upgrading XCode on these machines fixes this problem. | We have found that upgrading XCode on these machines fixes this problem. | ||
===I would like to know how I can build Qt on Solaris / HP-UX / AIX=== | ===I would like to know how I can build Qt on Solaris / HP-UX / AIX=== | ||
Line 6,834: | Line 6,664: | ||
http://blog.qt.io/2009/11/23/qtscript-in-46/ | http://blog.qt.io/2009/11/23/qtscript-in-46/ | ||
===How can I have several Qt versions installed under WINNT\system32?=== | ===How can I have several Qt versions installed under WINNT\system32?=== | ||
In order for your Qt applications to pick up the correct version of Qt installed under system32, you can build Qt with a custom name. You can do this using the qtlibinfix http://doc.qt.io/qt-5 | In order for your Qt applications to pick up the correct version of Qt installed under system32, you can build Qt with a custom name. You can do this using the qtlibinfix http://doc.qt.io/qt-5/configure-options.html option i.e | ||
< | <syntaxhighlight>configure -qtlibinfix customName </syntaxhighlight> | ||
Then your different Qt applications should be able to pick up its custom Qt version from the system32 directory. | Then your different Qt applications should be able to pick up its custom Qt version from the system32 directory. | ||
===How can I set an empty default value in QSpinBox?=== | ===How can I set an empty default value in QSpinBox?=== | ||
QSpinBox http://doc.qt.io/qt-5 | QSpinBox http://doc.qt.io/qt-5/qspinbox.html does not allow displaying an empty value by default. Support for an empty value can be added however by reimplementing textFromValue() http://doc.qt.io/qt-5/qspinbox.html#textFromValue and having it return an empty string under certain conditions. The example demonstrates this approach by returning the empty string instead of the minimum value. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class SpinBox : public QSpinBox | class SpinBox : public QSpinBox | ||
Line 6,854: | Line 6,684: | ||
Q_OBJECT | Q_OBJECT | ||
public: | public: | ||
SpinBox(QWidget *parent = | SpinBox(QWidget *parent = nullptr) | ||
: QSpinBox(parent) | : QSpinBox(parent) | ||
{} | {} | ||
int valueFromText(const QString &text) const override | |||
{ | { | ||
if (text.isEmpty()) | if (text.isEmpty()) | ||
Line 6,864: | Line 6,694: | ||
return QSpinBox::valueFromText(text); | return QSpinBox::valueFromText(text); | ||
} | } | ||
QString textFromValue(int v) const override | |||
{ | { | ||
if (v == minimum()) | if (v == minimum()) | ||
Line 6,881: | Line 6,711: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I use one horizontal scrollbar to scroll several QGraphicsViews?=== | ===How can I use one horizontal scrollbar to scroll several QGraphicsViews?=== | ||
In order to use one scrollbar to scroll several views, you can put your views and a QScrollBar http://doc.qt.io/qt-5 | In order to use one scrollbar to scroll several views, you can put your views and a QScrollBar http://doc.qt.io/qt-5/qscrollbar.html inside a widget and connect the scrollbar's value changed signal to the setValue() http://doc.qt.io/qt-5/qabstractslider.html#value-prop slots of the hidden horizontal scrollbars. In addition the ranges need to be kept in sync, although you can easily change this if you want to make it a bit smarter. See the following example for a demonstration: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Widget : public QWidget | class Widget : public QWidget | ||
Line 6,894: | Line 6,724: | ||
Q_OBJECT | Q_OBJECT | ||
public: | public: | ||
Widget(QWidget *parent = | Widget(QWidget *parent = nullptr) : QWidget(parent) | ||
{ | { | ||
QGraphicsScene *scene = new QGraphicsScene(); | QGraphicsScene *scene = new QGraphicsScene(); | ||
Line 6,938: | Line 6,768: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I get webkit to load local resources referenced within html returned from a custom scheme?=== | ===How can I get webkit to load local resources referenced within html returned from a custom scheme?=== | ||
When creating a custom network manager in order to support a custom protocol then webkit does not know that the custom scheme should be considered as a local scheme. Therefore its default security mechanism of preventing access to local resources (file:) from remote schemes is triggered because it thinks the custom protocol is a remote scheme. Therefore images for example, which are referenced via local files will not get loaded. In order to get around this, you can call QWebSecurityOrigin::addLocalScheme() http://doc.qt.io/qt-5/qwebsecurityorigin.html#addLocalScheme which adds the given scheme to the list of schemes that are considered equivalent to the file scheme. | When creating a custom network manager in order to support a custom protocol then webkit does not know that the custom scheme should be considered as a local scheme. Therefore its default security mechanism of preventing access to local resources (file:) from remote schemes is triggered because it thinks the custom protocol is a remote scheme. Therefore images for example, which are referenced via local files will not get loaded. In order to get around this, you can call QWebSecurityOrigin::addLocalScheme() http://doc.qt.io/qt-5/qwebsecurityorigin.html#addLocalScheme which adds the given scheme to the list of schemes that are considered equivalent to the file scheme. | ||
===How can I get a QStackedWidget to automatically switch size depending on the content of the page?=== | ===How can I get a QStackedWidget to automatically switch size depending on the content of the page?=== | ||
Line 6,958: | Line 6,788: | ||
The example below illustrates how this can be done: | The example below illustrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class SubWidget : public QWidget | class SubWidget : public QWidget | ||
{ | { | ||
Line 7,034: | Line 6,864: | ||
{ | { | ||
if (stackWidget->currentWidget() !=0) { | if (stackWidget->currentWidget() !=0) { | ||
stackWidget->currentWidget()->setSizePolicy(QSizePolicy::Ignored, | stackWidget->currentWidget()->setSizePolicy(QSizePolicy::Ignored, | ||
QSizePolicy::Ignored); | QSizePolicy::Ignored); | ||
} | } | ||
stackWidget->setCurrentIndex(idx); | stackWidget->setCurrentIndex(idx); | ||
stackWidget->currentWidget()->setSizePolicy(QSizePolicy::Expanding, | stackWidget->currentWidget()->setSizePolicy(QSizePolicy::Expanding, | ||
QSizePolicy::Expanding); | QSizePolicy::Expanding); | ||
adjustSize(); | adjustSize(); | ||
Line 7,055: | Line 6,885: | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I modify the color of some of the rows in my QTableWidget ?=== | ===How can I modify the color of some of the rows in my QTableWidget ?=== | ||
You can achieve this by reimplementing the delegate's paint() http://doc.qt.io/qt-5/ | You can achieve this by reimplementing the delegate's paint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#paint function and then modifying the palette for the rows you want. See the following example: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class ItemDelegate: public | class ItemDelegate: public QStyledItemDelegate | ||
{ | { | ||
public: | public: | ||
using QStyledItemDelegate::QStyledItemDelegate; | |||
void paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override | |||
void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const | |||
{ | { | ||
QPalette pal = option.palette; | QPalette pal = option.palette; | ||
Line 7,081: | Line 6,908: | ||
viewOption.palette.setColor(QPalette::HighlightedText, Qt::white); | viewOption.palette.setColor(QPalette::HighlightedText, Qt::white); | ||
} | } | ||
QStyledItemDelegate::paint(painter, viewOption, index); | |||
} | } | ||
}; | }; | ||
Line 7,099: | Line 6,924: | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I get hold of a cell widget's row?=== | ===How can I get hold of a cell widget's row?=== | ||
The widgets set on the cells have nothing to do with the contents of the table, so calling currentRow() http://doc.qt.io/qt-5 | The widgets set on the cells have nothing to do with the contents of the table, so calling currentRow() http://doc.qt.io/qt-5/qtablewidget.html#currentRow will return -1 when such cells are being edited. In order to get row or column information for a cell widget that is being edited, you can get hold of the widget using QApplication::focusWidget() http://doc.qt.io/qt-5/qapplication.html#focusWidget and get the model index using QTableView::indexAt() http://doc.qt.io/qt-5/qtableview.html#indexAt. Then it is easy to get the row or column information from the model index by calling row() http://doc.qt.io/qt-5/qmodelindex.html#row or column() http://doc.qt.io/qt-5/qmodelindex.html#column on it. | ||
The following example illustrates how this can be done: | The following example illustrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class TableWidget : public QTableWidget | class TableWidget : public QTableWidget | ||
Line 7,123: | Line 6,948: | ||
setRowCount(5); | setRowCount(5); | ||
setCellWidget(4,1, edit); | setCellWidget(4,1, edit); | ||
connect(edit, SIGNAL(textChanged(const QString)), this, SLOT(test1(const QString))); | connect(edit, SIGNAL(textChanged(const QString)), this, SLOT(test1(const QString))); | ||
} | } | ||
public slots: | public slots: | ||
Line 7,137: | Line 6,962: | ||
private: | private: | ||
QLineEdit *edit; | QLineEdit *edit; | ||
}; | }; | ||
Line 7,149: | Line 6,974: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Loading a Sql driver from a customized location=== | ===Loading a Sql driver from a customized location=== | ||
Line 7,158: | Line 6,983: | ||
Following is an example of how to load an OCI driver: | Following is an example of how to load an OCI driver: | ||
< | <syntaxhighlight lang="cpp"> | ||
QPluginLoader loader("C:\\MyApplicationFolder\\qsqloci4.dll"); | QPluginLoader loader("C:\\MyApplicationFolder\\qsqloci4.dll"); | ||
QObject *plugin = loader.instance(); | QObject *plugin = loader.instance(); | ||
Line 7,174: | Line 6,999: | ||
QSqlDatabase db = QSqlDatabase::addDatabase(ociDriver->create("QOCI")); | QSqlDatabase db = QSqlDatabase::addDatabase(ociDriver->create("QOCI")); | ||
</ | </syntaxhighlight> | ||
===How can I detect in the .pro file if I am compiling on a 32 bit or a 64 bit platform?=== | ===How can I detect in the .pro file if I am compiling on a 32 bit or a 64 bit platform?=== | ||
You can use QMAKE_HOST.arch for this. The QMAKE_HOST variable expresses host information about the machine running qmake and QMAKE_HOST.arch allows you to determine the target architecture. You can use it as follows: | You can use QMAKE_HOST.arch for this. The QMAKE_HOST variable expresses host information about the machine running qmake and QMAKE_HOST.arch allows you to determine the target architecture. You can use it as follows: | ||
< | <syntaxhighlight> | ||
win32-g++:contains(QMAKE_HOST.arch, x86_64):{ | win32-g++:contains(QMAKE_HOST.arch, x86_64):{ | ||
do something | do something | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I disable autoscroll when selecting a partially displayed column in a QTreeView?=== | ===How can I disable autoscroll when selecting a partially displayed column in a QTreeView?=== | ||
When clicking on a partially displayed column in a QTreeView http://doc.qt.io/qt-5 | When clicking on a partially displayed column in a QTreeView http://doc.qt.io/qt-5/qtreeview.html, the view will scroll to display the complete content of the column. If you want to disable this behavior, then you can subclass your view and reimplement scrollTo() http://doc.qt.io/qt-5/qtreeview.html#scrollTo to reset the value of the horizontal scrollbar to the value it had before the scroll. | ||
The following example demonstrates how this can be done: | The following example demonstrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class TreeWidget : public QTreeWidget | class TreeWidget : public QTreeWidget | ||
Line 7,214: | Line 7,039: | ||
item4->setText(1, tr("This is the very very second column")); | item4->setText(1, tr("This is the very very second column")); | ||
} | } | ||
void scrollTo ( const QModelIndex & index, ScrollHint hint = EnsureVisible ) | void scrollTo ( const QModelIndex & index, ScrollHint hint = EnsureVisible ) | ||
{ | { | ||
int myValue = horizontalScrollBar()->value(); | int myValue = horizontalScrollBar()->value(); | ||
Line 7,229: | Line 7,054: | ||
box.resize(150,200); | box.resize(150,200); | ||
box.show(); | box.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Can Qt Assistant be modified and redistributed with my application?=== | ===Can Qt Assistant be modified and redistributed with my application?=== | ||
Line 7,244: | Line 7,069: | ||
this includes the Qt Assistant documentation, so you will need to provide your | this includes the Qt Assistant documentation, so you will need to provide your | ||
own if you want to provide documentation on how to use Qt Assistant. | own if you want to provide documentation on how to use Qt Assistant. | ||
===How can I drag from e.g a QListWidget and drop in an editable QTableView?=== | ===How can I drag from e.g a QListWidget and drop in an editable QTableView?=== | ||
In order to enable dragging from the QListWidget, you need to reimplement dragEnterEvent() http://doc.qt.io/qt-5/qabstractitemview.html#dragEnterEvent and dragMoveEvent() http://doc.qt.io/qt-5/qabstractitemview.html#dragMoveEvent to accept the event. In addition you need to set setDragEnabled() http://doc.qt.io/qt-5/qabstractitemview.html#dragEnabled-prop to true to enable dragging of the view's items. | In order to enable dragging from the QListWidget, you need to reimplement dragEnterEvent() http://doc.qt.io/qt-5/qabstractitemview.html#dragEnterEvent and dragMoveEvent() http://doc.qt.io/qt-5/qabstractitemview.html#dragMoveEvent to accept the event. In addition you need to set setDragEnabled() http://doc.qt.io/qt-5/qabstractitemview.html#dragEnabled-prop to true to enable dragging of the view's items. | ||
For the QTableView you need to set setAcceptDrops() http://doc.qt.io/qt-5/qwidget.html#acceptDrops-prop to true in order to allow drops and then set a model on the view that has reimplemented setData() http://doc.qt.io/qt-5/qabstractitemmodel.html#setData and flags() http://doc.qt.io/qt-5/qabstractitemmodel.html#flags to allow editing of the model. | For the QTableView you need to set setAcceptDrops() http://doc.qt.io/qt-5/qwidget.html#acceptDrops-prop to true in order to allow drops and then set a model on the view that has reimplemented setData() http://doc.qt.io/qt-5/qabstractitemmodel.html#setData and flags() http://doc.qt.io/qt-5/qabstractitemmodel.html#flags to allow editing of the model. | ||
Line 7,253: | Line 7,078: | ||
The example below illustrates how this can be implemented: | The example below illustrates how this can be implemented: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include <QtCore> | #include <QtCore> | ||
class ListWidget : public QListWidget | class ListWidget : public QListWidget | ||
{ | { | ||
public: | public: | ||
ListWidget(QWidget *parent); | ListWidget(QWidget *parent); | ||
protected: | protected: | ||
void dragEnterEvent(QDragEnterEvent *e) | void dragEnterEvent(QDragEnterEvent *e) | ||
{ | { | ||
e->accept(); | e->accept(); | ||
} | } | ||
void dragMoveEvent(QDragMoveEvent *e) | void dragMoveEvent(QDragMoveEvent *e) | ||
{ | { | ||
e->accept(); | e->accept(); | ||
} | } | ||
}; | }; | ||
ListWidget::ListWidget(QWidget *parent) : QListWidget(parent) | ListWidget::ListWidget(QWidget *parent) : QListWidget(parent) | ||
{ | { | ||
addItem("Zero"); | addItem("Zero"); | ||
addItem("First"); | addItem("First"); | ||
addItem("Second"); | addItem("Second"); | ||
addItem("Third"); | addItem("Third"); | ||
addItem("Fourth"); | addItem("Fourth"); | ||
// The tree supports dragging of its own items | // The tree supports dragging of its own items | ||
setDragEnabled(true); | setDragEnabled(true); | ||
} | } | ||
class DragModel : public QAbstractTableModel | class DragModel : public QAbstractTableModel | ||
{ | { | ||
public: | public: | ||
DragModel(QObject *parent) | DragModel(QObject *parent) | ||
{ | { | ||
QStringList firstRow; | QStringList firstRow; | ||
QStringList secondRow; | QStringList secondRow; | ||
for (int i = 0; i < 5; i++ ) { | for (int i = 0; i < 5; i++ ) { | ||
firstRow.insert(i,"Row " + QString::number(i+1)); | firstRow.insert(i,"Row " + QString::number(i+1)); | ||
secondRow.insert(i,"Row " + QString::number(i+1)); | secondRow.insert(i,"Row " + QString::number(i+1)); | ||
} | } | ||
stringList << firstRow << secondRow; | stringList << firstRow << secondRow; | ||
} | } | ||
// Returns the number of rows | // Returns the number of rows | ||
int rowCount (const QModelIndex &parent = QModelIndex()) const | int rowCount (const QModelIndex &parent = QModelIndex()) const | ||
{ | { | ||
return 2; | return 2; | ||
} | } | ||
// Returns the number of columns | // Returns the number of columns | ||
int columnCount(const QModelIndex &parent = QModelIndex()) const | int columnCount(const QModelIndex &parent = QModelIndex()) const | ||
{ | { | ||
return 5; | return 5; | ||
} | } | ||
// Returns an appropriate value for the requested data. | // Returns an appropriate value for the requested data. | ||
// If the view requests an invalid index or if the role is not | // If the view requests an invalid index or if the role is not | ||
// Qt::DisplayRole, an invalid variant is returned. | // Qt::DisplayRole, an invalid variant is returned. | ||
// Any valid index that corresponds to a string for the index's column and row in | // Any valid index that corresponds to a string for the index's column and row in | ||
// the stringlist is returned | // the stringlist is returned | ||
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const | QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const | ||
{ | { | ||
if (!index.isValid()) | if (!index.isValid()) | ||
return QVariant(); | return QVariant(); | ||
if (role != Qt::DisplayRole) | if (role != Qt::DisplayRole) | ||
return QVariant(); | return QVariant(); | ||
QStringList list = (QStringList)stringList.at(index.row()); | QStringList list = (QStringList)stringList.at(index.row()); | ||
return list.at(index.column()); | return list.at(index.column()); | ||
} | } | ||
// Changes an item in the string list, but only if the following conditions | // Changes an item in the string list, but only if the following conditions | ||
// are met: | // are met: | ||
// * The index supplied is valid. | // * The index supplied is valid. | ||
// * The index corresponds to an item to be shown in a view. | // * The index corresponds to an item to be shown in a view. | ||
// * The role associated with rendering data is specified. | // * The role associated with rendering data is specified. | ||
// The dataChanged() signal is emitted if the item is changed. | // The dataChanged() signal is emitted if the item is changed. | ||
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) | bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) | ||
{ | { | ||
if (index.isValid() && role == Qt::EditRole) { | if (index.isValid() && role == Qt::EditRole) { | ||
// Set the data in the current cell to be value | // Set the data in the current cell to be value | ||
stringList[index.row()].replace(index.column(), value.toString()); | stringList[index.row()].replace(index.column(), value.toString()); | ||
// We only want to change the data for the current cell | // We only want to change the data for the current cell | ||
emit dataChanged(index, index); | emit dataChanged(index, index); | ||
return true; | return true; | ||
} | } | ||
return true; | return true; | ||
} | } | ||
// Return the default flags for this index in addition to flags | // Return the default flags for this index in addition to flags | ||
// that will accept drops and editing | // that will accept drops and editing | ||
Qt::ItemFlags flags(const QModelIndex & index) const | Qt::ItemFlags flags(const QModelIndex & index) const | ||
{ | { | ||
return QAbstractItemModel::flags(index) | Qt::ItemIsDropEnabled | Qt::ItemIsEditable; | return QAbstractItemModel::flags(index) | Qt::ItemIsDropEnabled | Qt::ItemIsEditable; | ||
} | } | ||
private: | private: | ||
// Each row will consist of a list of strings | // Each row will consist of a list of strings | ||
QList<QStringList> stringList; | QList<QStringList> stringList; | ||
}; | }; | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
QWidget widget; | QWidget widget; | ||
QHBoxLayout *layout = new QHBoxLayout(&widget); | QHBoxLayout *layout = new QHBoxLayout(&widget); | ||
ListWidget *listWidget = new ListWidget(&widget); | ListWidget *listWidget = new ListWidget(&widget); | ||
QTableView *tableView = new QTableView(&widget); | QTableView *tableView = new QTableView(&widget); | ||
DragModel *model = new DragModel(tableView); | DragModel *model = new DragModel(tableView); | ||
tableView->setModel(model); | tableView->setModel(model); | ||
// The table view can accept drops | // The table view can accept drops | ||
tableView->setAcceptDrops(true); | tableView->setAcceptDrops(true); | ||
layout->addWidget(listWidget); | layout->addWidget(listWidget); | ||
layout->addWidget(tableView); | layout->addWidget(tableView); | ||
widget.show(); | widget.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I build 64 bit Qt on a 32 bit system ?=== | ===How can I build 64 bit Qt on a 32 bit system ?=== | ||
If you want to build Qt as 64 bit, then you will first have to build the tools that Qt uses as 32 bit then the rest of the Qt libraries can be built in 64bit mode to enable you to build a 64bit version of your application. | If you want to build Qt as 64 bit, then you will first have to build the tools that Qt uses as 32 bit then the rest of the Qt libraries can be built in 64bit mode to enable you to build a 64bit version of your application. | ||
The following steps should build everything correctly (using 32bit cp to signify a 32bit Visual Studio command prompt and 64bit cp to signify a 64bit Visual Studio command prompt): | The following steps should build everything correctly (using 32bit cp to signify a 32bit Visual Studio command prompt and 64bit cp to signify a 64bit Visual Studio command prompt): | ||
* 32bit cp: Run configure with the options you want | * 32bit cp: Run configure with the options you want | ||
* 32bit cp: cd src\tools && nmake (note this will fail at the uic3 step, this is fine) | * 32bit cp: cd src\tools && nmake (note this will fail at the uic3 step, this is fine) | ||
* 64bit cp: cd src && nmake (note this will fail at the uic3 step, again this is fine) | * 64bit cp: cd src && nmake (note this will fail at the uic3 step, again this is fine) | ||
* 64bit cp: cd src\tools\uic3 && qmake | * 64bit cp: cd src\tools\uic3 && qmake | ||
* 64bit cp: cd src && nmake | * 64bit cp: cd src && nmake | ||
Bear in mind that this means you cannot use uic3 as part of your build process because of the fact it links against a 64bit library. Also note that you will not be able to run any of the applications you create with the 64 bit built Qt. You will have to deploy them to a 64 bit machine to run them. | Bear in mind that this means you cannot use uic3 as part of your build process because of the fact it links against a 64bit library. Also note that you will not be able to run any of the applications you create with the 64 bit built Qt. You will have to deploy them to a 64 bit machine to run them. | ||
===How can I convert a QString to char* and vice versa?=== | ===How can I convert a QString to char* and vice versa?=== | ||
In order to convert a QString http://doc.qt.io/qt-5 | In order to convert a QString http://doc.qt.io/qt-5/qstring.html to a char*, then you first need to get a local8Bit representation of the string by calling toLocal8Bit() http://doc.qt.io/qt-5/qstring.html#toLocal8Bit on it which will return a QByteArray http://doc.qt.io/qt-5/qbytearray.html. Then call data() http://doc.qt.io/qt-5/qbytearray.html#data on the QByteArray to get a pointer to the data stored in the byte array. | ||
See the following example for a demonstration: | See the following example for a demonstration: | ||
< | <syntaxhighlight lang="cpp"> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
Line 7,402: | Line 7,227: | ||
} | } | ||
</ | </syntaxhighlight> | ||
Note that it is necessary to store the bytearray before you call data() on it, a call like the following | Note that it is necessary to store the bytearray before you call data() on it, a call like the following | ||
< | <syntaxhighlight lang="cpp"> | ||
const char *c_str2 = str2.toLocal8Bit().data(); | const char *c_str2 = str2.toLocal8Bit().data(); | ||
</ | </syntaxhighlight> | ||
will make the application crash as the QByteArray has not been stored and hence no longer exists | will make the application crash as the QByteArray has not been stored and hence no longer exists | ||
To convert a char* to a QString you can use the QString constructor that takes a QLatin1String http://doc.qt.io/qt-5 | To convert a char* to a QString you can use the QString constructor that takes a QLatin1String http://doc.qt.io/qt-5/qlatin1string.html to ensure the locale encoded string is correct with fromLocal8Bit() http://doc.qt.io/qt-5/qstring.html#fromLocal8Bit, e.g: | ||
< | <syntaxhighlight lang="cpp"> | ||
QString string = QString(QLatin1String(c_str2)); | QString string = QString(QLatin1String(c_str2)); | ||
QString string = QString::fromLocal8Bit(c_str2); | QString string = QString::fromLocal8Bit(c_str2); | ||
</ | </syntaxhighlight> | ||
In addition, if you want to just print out the string then you can use qPrintable() http://doc.qt.io/qt-5/qtglobal.html#qPrintable as a quick means to do this without having to convert to a char *. For example: | In addition, if you want to just print out the string then you can use qPrintable() http://doc.qt.io/qt-5/qtglobal.html#qPrintable as a quick means to do this without having to convert to a char *. For example: | ||
< | <syntaxhighlight lang="cpp"> | ||
printf("str2: %s", qPrintable(str1)); | printf("str2: %s", qPrintable(str1)); | ||
</ | </syntaxhighlight> | ||
===How can I programatically find out which rows/items are visible in my view ?=== | ===How can I programatically find out which rows/items are visible in my view ?=== | ||
Qt does not support retrieving the actual visible items in the viewport, you will have to calculate this yourself by listening to the valueChanged() http://doc.qt.io/qt-5/qabstractslider.html#valueChanged signal of the scrollbar to get the topmost row/item. | Qt does not support retrieving the actual visible items in the viewport, you will have to calculate this yourself by listening to the valueChanged() http://doc.qt.io/qt-5/qabstractslider.html#valueChanged signal of the scrollbar to get the topmost row/item. | ||
To get the bottom row, you can pass in the height of the view to QHeaderView::visualIndexAt() http://doc.qt.io/qt-5/qheaderview.html#visualIndexAt. | To get the bottom row, you can pass in the height of the view to QHeaderView::visualIndexAt() http://doc.qt.io/qt-5/qheaderview.html#visualIndexAt. | ||
Qt supports two ways of scrolling, a pixel-based way and also an item-based way. Using the item-based http://doc.qt.io/qt-5/qabstractitemview.html#ScrollMode-enum way will make the calculation easier. | Qt supports two ways of scrolling, a pixel-based way and also an item-based way. Using the item-based http://doc.qt.io/qt-5/qabstractitemview.html#ScrollMode-enum way will make the calculation easier. | ||
The following example demonstrates how this can be done: | The following example demonstrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class TableWidget : public QTableWidget | class TableWidget : public QTableWidget | ||
Line 7,447: | Line 7,272: | ||
setHorizontalScrollMode(QAbstractItemView::ScrollPerItem); | setHorizontalScrollMode(QAbstractItemView::ScrollPerItem); | ||
setVerticalScrollMode(QAbstractItemView::ScrollPerItem); | setVerticalScrollMode(QAbstractItemView::ScrollPerItem); | ||
connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), | connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), | ||
this, SLOT(outputColumns(int))); | this, SLOT(outputColumns(int))); | ||
connect(verticalScrollBar(), SIGNAL(valueChanged(int)), | connect(verticalScrollBar(), SIGNAL(valueChanged(int)), | ||
this, SLOT(outputRows(int))); | this, SLOT(outputRows(int))); | ||
} | } | ||
Line 7,477: | Line 7,302: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How do I create a sln from a SUBDIRS template?=== | ===How do I create a sln from a SUBDIRS template?=== | ||
All you need to do is: | All you need to do is: | ||
< | <syntaxhighlight> qmake -tp vc</syntaxhighlight> | ||
on the pro file and it will create a solution file for you. | on the pro file and it will create a solution file for you. | ||
===When setting a global color group on my Mac everything goes black. What is the problem?=== | ===When setting a global color group on my Mac everything goes black. What is the problem?=== | ||
Line 7,492: | Line 7,317: | ||
You should avoid global objects of non POD-type (i.e. any type with a constructor). | You should avoid global objects of non POD-type (i.e. any type with a constructor). | ||
===How to minimize memory footprint in Qt for Embedded Linux?=== | ===How to minimize memory footprint in Qt for Embedded Linux?=== | ||
There's no single magical step that can reduce the memory footprint, but there are several things you might wish to consider. One is the use of more aggressive optimization. The other is to use the following flags during configuration: | There's no single magical step that can reduce the memory footprint, but there are several things you might wish to consider. One is the use of more aggressive optimization. The other is to use the following flags during configuration: | ||
< | <syntaxhighlight>-no-stl | ||
-no-exceptions </ | -no-exceptions </syntaxhighlight> | ||
To add the -o3 as a compiler option is pretty straightforward: | To add the -o3 as a compiler option is pretty straightforward: | ||
In the .pro file, add the following lines: | In the .pro file, add the following lines: | ||
< | <syntaxhighlight>QMAKE_CFLAGS_DEBUG +=o3 | ||
QMAKE_CXXFLAGS_DEBUG +=o3 </ | QMAKE_CXXFLAGS_DEBUG +=o3 </syntaxhighlight> | ||
You should use RELEASE instead of debug in your release version. | You should use RELEASE instead of debug in your release version. | ||
Also make sure you remove unnecessary options from your configuration. You should remove any features that you will not use in your final applications. | Also make sure you remove unnecessary options from your configuration. You should remove any features that you will not use in your final applications. | ||
===Who implements the antialiasing? You or the platform?=== | ===Who implements the antialiasing? You or the platform?=== | ||
Line 7,516: | Line 7,341: | ||
* QImage http://doc.qt.io/qt-5 | * QImage http://doc.qt.io/qt-5/qimage.html: implemented in Qt | ||
* QWidget http://doc.qt.io/qt-5 | * QWidget http://doc.qt.io/qt-5/qwidget.html: platform dependent, Qt on Windows, XRender on X11, CoreGraphics on Mac OS X | ||
* QPixmap http://doc.qt.io/qt-5 | * QPixmap http://doc.qt.io/qt-5/qpixmap.html: same as QWidget | ||
* QPrinter http://doc.qt.io/qt-5 | * QPrinter http://doc.qt.io/qt-5/qprinter.html: does not have antialiasing because of high dpi. | ||
* PDF: antialiasing is done by the viewer | * PDF: antialiasing is done by the viewer | ||
* OpenGL http://doc.qt.io/qt-5 | * OpenGL http://doc.qt.io/qt-5/qtopengl.html: implemented in OpenGL based on supersampling | ||
===What function can I replace the QPaintDeivce::handle() function from Qt 3 in Qt 4 with?=== | ===What function can I replace the QPaintDeivce::handle() function from Qt 3 in Qt 4 with?=== | ||
In Qt 3 all of the paint devices were tied one-to-one with an underlying object. QPixmap http://doc.qt.io/qt-5 | In Qt 3 all of the paint devices were tied one-to-one with an underlying object. QPixmap http://doc.qt.io/qt-5/qpixmap.html was a Windows HBITMAP or X11 pixmap for example. This tight connection between native and Qt classes no longer exists in Qt 4, but we have created mappings in the places where connections do exist. Toplevel widgets have a winId() http://doc.qt.io/qt-5/qwidget.html#winId for example and QPixmap a to/ fromWinHBITMAP() http://doc.qt.io/qt-5/qpixmap.html#fromWinHBITMAP, QWidget has getDc() http://doc.qt.io/qt-5/qwidget.html#getDC and releaseDC() http://doc.qt.io/qt-5/qwidget.html#releaseDC etc. | ||
So the new functions are spread over several classes and in most cases you could simply use one of the new alternatives. If you want to convert between Windows bitmaps and our pixmaps for example then you could use QPixmap::fromWinHBITMAP(). | So the new functions are spread over several classes and in most cases you could simply use one of the new alternatives. If you want to convert between Windows bitmaps and our pixmaps for example then you could use QPixmap::fromWinHBITMAP(). | ||
If you wish to use GDI directly on the widget then this is more tricky since all drawing happens in the backingstore, so you would also have to draw with GDI on it. That could be achieved in the paintEvent() http://doc.qt.io/qt-5 | If you wish to use GDI directly on the widget then this is more tricky since all drawing happens in the backingstore, so you would also have to draw with GDI on it. That could be achieved in the paintEvent() http://doc.qt.io/qt-5/qwidget.html#paintEvent by calling | ||
< | <syntaxhighlight lang="cpp">painter.paintEngine()->getDC() </syntaxhighlight> | ||
and then later releaseDC(). | and then later releaseDC(). | ||
===Why does the pushbutton suddenly become square on the Mac when it gets down to a certain size?=== | ===Why does the pushbutton suddenly become square on the Mac when it gets down to a certain size?=== | ||
Line 7,548: | Line 7,373: | ||
were to use a mini button there we would have to change the widget's font and | were to use a mini button there we would have to change the widget's font and | ||
this would be disturbing, particularly for people who have a certain font set. | this would be disturbing, particularly for people who have a certain font set. | ||
===How can I keep the pixmap background at all times for flat buttons?=== | ===How can I keep the pixmap background at all times for flat buttons?=== | ||
Line 7,555: | Line 7,380: | ||
See the following example: | See the following example: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
Line 7,584: | Line 7,409: | ||
return ret; | return ret; | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I get rid of the focus rectangle for a QTextEdit in the motif style?=== | ===How can I get rid of the focus rectangle for a QTextEdit in the motif style?=== | ||
In order to get rid of the focus rectangle of a text edit, you need to subclass the QMotifStyle http://doc.qt.io/qt-5 | In order to get rid of the focus rectangle of a text edit, you need to subclass the QMotifStyle http://doc.qt.io/qt-5/qmotifstyle.html and reimplement drawControl() http://doc.qt.io/qt-5/qmotifstyle.html#drawControl to draw nothing when the control element is CE_FocusFrame http://doc.qt.io/qt-5/qstyle.html#ControlElement-enum. | ||
The example below demonstrates how this can be done. | The example below demonstrates how this can be done. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include <QtWidgets> | |||
class Style : public QMotifStyle | class Style : public QMotifStyle | ||
{ | { | ||
public: | |||
Style() {} | |||
void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const override | |||
{ | |||
if (element == CE_FocusFrame) | |||
return; | |||
QMotifStyle::drawControl(element, option, painter, widget); | |||
} | |||
}; | }; | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
Style *s = new Style(); | |||
app.setStyle(s); | |||
QWidget wid; | |||
QPushButton *button = new QPushButton("text", &wid); | |||
QTextEdit *edit = new QTextEdit(&wid); | |||
QVBoxLayout *layout = new QVBoxLayout(&wid); | |||
layout->addWidget(button); | |||
layout->addWidget(edit); | |||
wid.show(); | |||
return app.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
===Can I resize a toplevel window to zero height and zero width?=== | ===Can I resize a toplevel window to zero height and zero width?=== | ||
This will depend upon the different window managers. Windows for example enforces your top level windows to have a minimum size, so it is not possible to resize them smaller than that size using Qt. Other window managers may allow this though, if you have given your window a minimumSizeHint() http://doc.qt.io/qt-5 | This will depend upon the different window managers. Windows for example enforces your top level windows to have a minimum size, so it is not possible to resize them smaller than that size using Qt. Other window managers may allow this though, if you have given your window a minimumSizeHint() http://doc.qt.io/qt-5/qwidget.html#minimumSizeHint-prop of 0,0. | ||
===After installing a new Qt version, Designer crashes when it loads the plugins, what's wrong?=== | ===After installing a new Qt version, Designer crashes when it loads the plugins, what's wrong?=== | ||
Line 7,639: | Line 7,461: | ||
designer\plugins directory and rebuild all your Designer plugins and if you | designer\plugins directory and rebuild all your Designer plugins and if you | ||
have created additional plugins then rebuild them too. | have created additional plugins then rebuild them too. | ||
===How can I easily create a Visual Studio project from my existing pro file=== | ===How can I easily create a Visual Studio project from my existing pro file=== | ||
Line 7,649: | Line 7,471: | ||
so it will create a valid Visual Studio project file regardless of the | so it will create a valid Visual Studio project file regardless of the | ||
template you use. The only exception is the SUBDIRS template. | template you use. The only exception is the SUBDIRS template. | ||
===Is there a way to tell qmake to copy files into my application bundle (e.g. private frameworks, sound files, etc.)?=== | ===Is there a way to tell qmake to copy files into my application bundle (e.g. private frameworks, sound files, etc.)?=== | ||
Line 7,656: | Line 7,478: | ||
Here's an example where we add a framework to the bundle | Here's an example where we add a framework to the bundle | ||
< | <syntaxhighlight># Rest of the .pro file | ||
PRIVATE_FRAMEWORKS.files = /path/to/MyFramework.framework | PRIVATE_FRAMEWORKS.files = /path/to/MyFramework.framework | ||
PRIVATE_FRAMEWORKS.path = Contents/Frameworks | PRIVATE_FRAMEWORKS.path = Contents/Frameworks | ||
QMAKE_BUNDLE_DATA += PRIVATE_FRAMEWORKS</ | QMAKE_BUNDLE_DATA += PRIVATE_FRAMEWORKS</syntaxhighlight> | ||
===Which UML modelers can be used to perform reverse engineering on code written with Qt?=== | ===Which UML modelers can be used to perform reverse engineering on code written with Qt?=== | ||
Line 7,671: | Line 7,493: | ||
http://uml.sourceforge.net/index.php | http://uml.sourceforge.net/index.php | ||
===How does Qt pick a font for the application?=== | ===How does Qt pick a font for the application?=== | ||
Line 7,685: | Line 7,507: | ||
http://doc.qt.io/qt-5/qfont.html | http://doc.qt.io/qt-5/qfont.html | ||
===How can I make one of my toolbars appear on the right hand side of the topdock area?=== | ===How can I make one of my toolbars appear on the right hand side of the topdock area?=== | ||
There is no API for this, but you can play around with the size policies http://doc.qt.io/qt-5/qsizepolicy.html#Policy-enum to achieve what you want. See the following example: | There is no API for this, but you can play around with the size policies http://doc.qt.io/qt-5/qsizepolicy.html#Policy-enum to achieve what you want. See the following example: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
QMainWindow box; | |||
QToolBar *toolBar = new QToolBar(&box); | |||
QToolBar *toolBar2 = new QToolBar(&box); | |||
toolBar->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); | |||
box.addToolBar(toolBar); | |||
box.addToolBar(toolBar2); | |||
QAction *action = toolBar->addAction(one); | |||
QAction *action2 = toolBar2->addAction(right); | |||
box.show(); | |||
return app.exec(); | |||
} | } | ||
</ | |||
</syntaxhighlight> | |||
===My custom widget appears as a grey rectangle in Designer. How can I fix this ?=== | ===My custom widget appears as a grey rectangle in Designer. How can I fix this ?=== | ||
The reason you only see a grey rectangle on the form is probably that you have not reimplemented domXml() http://doc.qt.io/qt-5 | The reason you only see a grey rectangle on the form is probably that you have not reimplemented domXml() http://doc.qt.io/qt-5/qdesignercustomwidgetinterface.html#domXml. You need to reimplement domXml() to at least specify the geometry property. See the following code for an example: | ||
< | <syntaxhighlight lang="cpp"> | ||
QString MyWidgetPlugin::domXml() const | QString MyWidgetPlugin::domXml() const | ||
{ | { | ||
Line 7,734: | Line 7,556: | ||
" </widget>"); | " </widget>"); | ||
} | } | ||
</ | </syntaxhighlight> | ||
See the documentation: | See the documentation: | ||
Line 7,748: | Line 7,570: | ||
type the name of the executable with an & at the end, this will allow you to | type the name of the executable with an & at the end, this will allow you to | ||
open new instances. | open new instances. | ||
===Can I use your icons in my product?=== | ===Can I use your icons in my product?=== | ||
The icons that are used in Qt's tools, i.e. Qt Designer http://doc.qt.io/qt-5 | The icons that are used in Qt's tools, i.e. Qt Designer http://doc.qt.io/qt-5/designer-manual.html, Qt Linguist http://doc.qt.io/qt-5/linguist-manual.html and Qt Assistant http://doc.qt.io/qt-5/assistant-manual.html are designed specifically by us. You have permission to use these in your own application, but you will need to add a notice that indicates that the copyright of the icons belong to The Qt Company. | ||
===How can I represent rich text in an itemview ?=== | ===How can I represent rich text in an itemview ?=== | ||
The default delegate does not process or interpret HTML tags. The representation of the displayed information is handled at a very low level in the QAbstractItemDelegate http://doc.qt.io/qt-5 | The default delegate does not process or interpret HTML tags. The representation of the displayed information is handled at a very low level in the QAbstractItemDelegate http://doc.qt.io/qt-5/qabstractitemdelegate.html. | ||
You could choose to implement this in a custom delegate, and then handle this in the QAbstractItemDelegate::paint() http://doc.qt.io/qt-5 | You could choose to implement this in a custom delegate, and then handle this in the QAbstractItemDelegate::paint() http://doc.qt.io/qt-5/qabstractitemdelegate.html#paint method. The example which illustrates this best is under ./examples/itemviews/pixelator http://doc.qt.io/qt-5/itemviews-pixelator.html in your Qt directory. | ||
An alternative approach which is only feasible for small applications, is to actually set a style sheet on supported widgets on the QTableView http://doc.qt.io/qt-5/qtableview.html cells and style them accordingly. | |||
===How can I lay out a splitter so that one widget takes 2/3 of the space and another 1/3?=== | ===How can I lay out a splitter so that one widget takes 2/3 of the space and another 1/3?=== | ||
You can use QSplitter::setSizes() http://doc.qt.io/qt-5/qsplitter.html#setSizes for this. | You can use QSplitter::setSizes() http://doc.qt.io/qt-5/qsplitter.html#setSizes for this. | ||
===QTextEdit gets a performance problem when filling up=== | ===QTextEdit gets a performance problem when filling up=== | ||
QTextEdit http://doc.qt.io/qt-5 | QTextEdit http://doc.qt.io/qt-5/qtextedit.html is optimized for working with paragraphs and it is not designed for handling very large paragraphs. When having very long paragraphs you will run into a performance problem at some point, when this will happen depends on the speed of your machine, the font you are using etc. We are not planning to change this design since the users generally split their documents into paragraphs. | ||
A solution to this problem can be to use a QPlainTextEdit http://doc.qt.io/qt-5/qplaintextedit.html instead of a QTextedit and set the maximum number of blocks using setMaximumBlockCount() http://doc.qt.io/qt-5/qplaintextedit.html#maximumBlockCount-prop. | |||
===Why doesn't OpenGL improve the performance of the chip demo?=== | ===Why doesn't OpenGL improve the performance of the chip demo?=== | ||
Line 7,784: | Line 7,606: | ||
Whether or not OpenGL improves performance is down to the scenario in which you use it, but in most cases it is better. It just isn't for widget drawing nor for many of the Qt examples. If you had a picture gallery it would show off the performance improvements that OpenGL can bring. | Whether or not OpenGL improves performance is down to the scenario in which you use it, but in most cases it is better. It just isn't for widget drawing nor for many of the Qt examples. If you had a picture gallery it would show off the performance improvements that OpenGL can bring. | ||
===How can I get rid of the white space outside the cells of my table?=== | ===How can I get rid of the white space outside the cells of my table?=== | ||
If you don't need all of your header sections to be resizable, then you can achieve this by setting the resizeMode http://doc.qt.io/qt-5/qheaderview.html#ResizeMode-enum to stretch for one or more of the header sections: | If you don't need all of your header sections to be resizable, then you can achieve this by setting the resizeMode http://doc.qt.io/qt-5/qheaderview.html#ResizeMode-enum to stretch for one or more of the header sections: | ||
< | <syntaxhighlight lang="cpp"> | ||
table->horizontalHeader()->setResizeMode(4, QHeaderView::Stretch); | table->horizontalHeader()->setResizeMode(4, QHeaderView::Stretch); | ||
</ | </syntaxhighlight> | ||
If you do need all of your header sections to be resizeable, then you need to reimplement the sizeHint() http://doc.qt.io/qt-5/qwidget.html#sizeHint-prop to account for the size of the cells and headers in the table. | If you do need all of your header sections to be resizeable, then you need to reimplement the sizeHint() http://doc.qt.io/qt-5/qwidget.html#sizeHint-prop to account for the size of the cells and headers in the table. | ||
Then you need to set this size to be the maximum size of the table. Since you allow resizing of the table's columns, you also need to connect a slot to the sectionResized http://doc.qt.io/qt-5 | Then you need to set this size to be the maximum size of the table. Since you allow resizing of the table's columns, you also need to connect a slot to the sectionResized http://doc.qt.io/qt-5/qheaderview.html#sectionResized signal and call setMaximumSize(sizeHint()) in there. | ||
The example below demonstrates how this can be done for a toplevel table. If you need this to work for a table that is embedded into another widget, then you need to set the sizePolicy http://doc.qt.io/qt-5 | The example below demonstrates how this can be done for a toplevel table. If you need this to work for a table that is embedded into another widget, then you need to set the sizePolicy http://doc.qt.io/qt-5/qsizepolicy.html#Policy-enum to fixed, so that the sizeHint() is the only alternative. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class TableWidget : public QTableWidget | class TableWidget : public QTableWidget | ||
Line 7,846: | Line 7,668: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Do I have to delete my child widgets?=== | ===Do I have to delete my child widgets?=== | ||
Ordinarily no. Child widgets will be automatically destroyed by the parent widget when that is destroyed. See the documentation of ~QObject() http://doc.qt.io/qt-5/qobject.html#dtor.QObject for details. | Ordinarily no. Child widgets will be automatically destroyed by the parent widget when that is destroyed. See the documentation of ~QObject() http://doc.qt.io/qt-5/qobject.html#dtor.QObject for details. | ||
===Is there a listing of the details of the changes in Qt 4 and what needs to be done to migrate from Qt 3.3.x to Qt 4?=== | ===Is there a listing of the details of the changes in Qt 4 and what needs to be done to migrate from Qt 3.3.x to Qt 4?=== | ||
Line 7,857: | Line 7,679: | ||
===How do I export my form without changing the generated code?=== | ===How do I export my form without changing the generated code?=== | ||
Simply click on your form in Qt Designer and then go to the *Property Editor*. Expand the *name* property and you will be given an *export macro* property. In there you can specify the macro you use for specifying that the class should be exported. | Simply click on your form in Qt Designer and then go to the *Property Editor*. Expand the *name* property and you will be given an *export macro* property. In there you can specify the macro you use for specifying that the class should be exported. | ||
===Is there a simple way to change the coordinate system of QPainter so that the logical coordinates start from the lower left corner instead of the upper left corner?=== | ===Is there a simple way to change the coordinate system of QPainter so that the logical coordinates start from the lower left corner instead of the upper left corner?=== | ||
There is no direct way to do this, but what you can do is to define your scale matrix and apply it to all primitives and positions instead of applying it to QPainter http://doc.qt.io/qt-5 | There is no direct way to do this, but what you can do is to define your scale matrix and apply it to all primitives and positions instead of applying it to QPainter http://doc.qt.io/qt-5/qpainter.html itself. Alternatively, you can set the scale matrix on the painter and draw all your primitives, then unset the transformation and draw all your text. | ||
===How can I use plugins in a statically built Qt library in Qt 4?=== | ===How can I use plugins in a statically built Qt library in Qt 4?=== | ||
When creating your own plugins, you need to use Q_EXPORT_PLUGIN2 http://doc.qt.io/qt-5 | When creating your own plugins, you need to use Q_EXPORT_PLUGIN2 http://doc.qt.io/qt-5/qtplugin.html#Q_EXPORT_PLUGIN2 in your plugin code to export the plugin and then Q_IMPORT_PLUGIN http://doc.qt.io/qt-5/qtplugin.html#Q_IMPORT_PLUGIN in your application to be able to use the plugin there. In addition you need to add | ||
< | <syntaxhighlight lang="cpp"> QTPLUGIN += pluginname</syntaxhighlight> | ||
Line 7,880: | Line 7,702: | ||
===Is there a way I can get rid of the icon in the mdi child window's titlebar?=== | ===Is there a way I can get rid of the icon in the mdi child window's titlebar?=== | ||
You can easily hide this icon by calling setWindowIcon() http://doc.qt.io/qt-5 | You can easily hide this icon by calling setWindowIcon() http://doc.qt.io/qt-5/qwidget.html#windowIcon-prop with a pixmap that has a transparent color, e.g: | ||
< | <syntaxhighlight lang="cpp"> | ||
QPixmap pix(16,16); | QPixmap pix(16,16); | ||
pix.fill(Qt::transparent); | pix.fill(Qt::transparent); | ||
child->setWindowIcon(QIcon(pix)); | child->setWindowIcon(QIcon(pix)); | ||
</ | </syntaxhighlight> | ||
===How can I find subitems in a QTreeWidget using findItems?=== | ===How can I find subitems in a QTreeWidget using findItems?=== | ||
Line 7,896: | Line 7,718: | ||
The following example illustrates how this can be done: | The following example illustrates how this can be done: | ||
< | <syntaxhighlight lang="cpp">#include <QtWidgets> | ||
int main( int argc, char** argv ) | int main( int argc, char** argv ) | ||
{ | { | ||
QApplication app( argc, argv ); | QApplication app( argc, argv ); | ||
QTreeWidget* treeWidget = new QTreeWidget; | QTreeWidget* treeWidget = new QTreeWidget; | ||
treeWidget->setWindowTitle(Test); | treeWidget->setWindowTitle(Test); | ||
treeWidget->setColumnCount(4); | treeWidget->setColumnCount(4); | ||
QTreeWidgetItem* item = NULL; | QTreeWidgetItem* item = NULL; | ||
for (int l=0; l<10; l++) | for (int l=0; l<10; l++) | ||
{ | { | ||
item = new QTreeWidgetItem(treeWidget); | |||
item->setText(0, QString::number(l)); | |||
item->setText(1, QString::number(l)); | |||
item->setText(2, QString::number(l)); | |||
item->setText(3, test); | |||
item->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsSelectable | Qt::ItemIsEnabled ); | |||
item->setCheckState(0, Qt::Unchecked); | |||
} | } | ||
QList<QTreeWidgetItem*> items = treeWidget->findItems(test,Qt::MatchExactly, 3); | QList<QTreeWidgetItem*> items = treeWidget->findItems(test,Qt::MatchExactly, 3); | ||
int num = items.count(); | int num = items.count(); | ||
qDebug(first time: %d, num); | qDebug(first time: %d, num); | ||
for (int l=0; l<5; l++) | for (int l=0; l<5; l++) | ||
{ | { | ||
item = new QTreeWidgetItem(treeWidget->topLevelItem(4)); | |||
item->setText(0, QString::number(l)); | |||
item->setText(1, QString::number(l)); | |||
item->setText(2, QString::number(l)); | |||
item->setText(3, test); | |||
item->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsSelectable | Qt::ItemIsEnabled ); | |||
item->setCheckState(0, Qt::Unchecked); | |||
} | } | ||
treeWidget->show(); | treeWidget->show(); | ||
items = treeWidget->findItems(test, Qt::MatchExactly, 3); | items = treeWidget->findItems(test, Qt::MatchExactly, 3); | ||
items = treeWidget->findItems(test, Qt::MatchExactly | Qt::MatchRecursive, 3); | items = treeWidget->findItems(test, Qt::MatchExactly | Qt::MatchRecursive, 3); | ||
num = items.count(); | num = items.count(); | ||
qDebug(Second time: %d, num); | qDebug(Second time: %d, num); | ||
return app.exec(); | return app.exec(); | ||
}</ | }</syntaxhighlight> | ||
===Displaying a big pixmap or image does not work. How can this be fixed?=== | ===Displaying a big pixmap or image does not work. How can this be fixed?=== | ||
The windowing systems have some limitations in regards to the size of pixmaps that they are capable of rendering. The actual size of an image that is supported varies from machine to machine and depends on OS, graphics hardware, memory and other running applications. In general we recommend that one does not create pixmaps that are significantly larger than your screen. When you load a QImage http://doc.qt.io/qt-5/qimage.html and you want to draw this, it is implicitly converted to a pixmap so you are subject to this limitation. | The windowing systems have some limitations in regards to the size of pixmaps that they are capable of rendering. The actual size of an image that is supported varies from machine to machine and depends on OS, graphics hardware, memory and other running applications. In general we recommend that one does not create pixmaps that are significantly larger than your screen. When you load a QImage http://doc.qt.io/qt-5/qimage.html and you want to draw this, it is implicitly converted to a pixmap so you are subject to this limitation. | ||
To work around this, then if it is possible in your case, you can make your image smaller and load that one. If this is not an option, then you can split your big image into smaller chunks, say 1000 by 1000 pixels and draw the big image as adjacent parts of the big image. | To work around this, then if it is possible in your case, you can make your image smaller and load that one. If this is not an option, then you can split your big image into smaller chunks, say 1000 by 1000 pixels and draw the big image as adjacent parts of the big image. | ||
===Does QPainter support alpha channels with a QPrinter ?=== | ===Does QPainter support alpha channels with a QPrinter ?=== | ||
It is highly system dependent and driver dependent if the printer supports alpha channel or not. The PostScript language does not have support for alpha channel so PostScript printers will not support this. Very few Windows printers also support alpha channels. There are however some solutions that can be used to emulate support for the alpha channel. | It is highly system dependent and driver dependent if the printer supports alpha channel or not. The PostScript language does not have support for alpha channel so PostScript printers will not support this. Very few Windows printers also support alpha channels. There are however some solutions that can be used to emulate support for the alpha channel. | ||
There are basically two algorithms you can use, one is to draw into a QPixmap http://doc.qt.io/qt-5/qpixmap.html#QPixmap-3 and then convert it to a QImage http://doc.qt.io/qt-5 | There are basically two algorithms you can use, one is to draw into a QPixmap http://doc.qt.io/qt-5/qpixmap.html#QPixmap-3 and then convert it to a QImage http://doc.qt.io/qt-5/qimage.html or directly to a QImage and draw it using QPainter::drawImage() http://doc.qt.io/qt-5/qpainter.html#drawImage passing either Qt::OrderedAlphaDither or Qt::DiffuseAlphaDither as the image conversion flags http://doc.qt.io/qt-5/qt.html#ImageConversionFlag-enum. | ||
The second solution, which is useful if you have a complex scene, is to draw into an intermediate pixmap the size of your printer. However since images/pixmaps should not be larger than the screen size, you may have to split the drawing into multiple chunks, depending on the resolution of the printer. | The second solution, which is useful if you have a complex scene, is to draw into an intermediate pixmap the size of your printer. However since images/pixmaps should not be larger than the screen size, you may have to split the drawing into multiple chunks, depending on the resolution of the printer. | ||
< | <syntaxhighlight lang="cpp"> | ||
void print() | void print() | ||
{ | { | ||
Line 7,974: | Line 7,796: | ||
} | } | ||
} | } | ||
} | } | ||
</ | </syntaxhighlight> | ||
===What is the Qt Visual Studio add-in?=== | ===What is the Qt Visual Studio add-in?=== | ||
Line 7,983: | Line 7,805: | ||
<ul><li>Wizards for creating new Qt projects and classes.</li><li>Automated build setup for the Meta-Object Compiler(moc), the User Interface Compiler (uic), and the Resource Compiler (rcc).</li><li>Import and export of Qt Project {.pro} and Project Include {.pri} files.</li><li>Integrated Qt resource management.</li><li>Integrated Qt documentation.</li><li>Debugging extensions for Qt data types.</li> </ul> | <ul><li>Wizards for creating new Qt projects and classes.</li><li>Automated build setup for the Meta-Object Compiler(moc), the User Interface Compiler (uic), and the Resource Compiler (rcc).</li><li>Import and export of Qt Project {.pro} and Project Include {.pri} files.</li><li>Integrated Qt resource management.</li><li>Integrated Qt documentation.</li><li>Debugging extensions for Qt data types.</li> </ul> | ||
===How can I trigger the redraw of a single QGraphicsItem?=== | ===How can I trigger the redraw of a single QGraphicsItem?=== | ||
You can easily call QGraphicsItem::update() http://doc.qt.io/qt-5 | You can easily call QGraphicsItem::update() http://doc.qt.io/qt-5/qgraphicsitem.html#update to only mark one item as dirty, and have this item redrawn. | ||
===I have a problem installing a Qt RPM/deb/etc. package.=== | ===I have a problem installing a Qt RPM/deb/etc. package.=== | ||
You should contact the maintainer/creator of the package. These packages are | You should contact the maintainer/creator of the package. These packages are | ||
not created/maintained by Qt Development Frameworks, only the .tar.gz source archive is. | not created/maintained by Qt Development Frameworks, only the .tar.gz source archive is. | ||
===Is a desktop simulation tool available?=== | ===Is a desktop simulation tool available?=== | ||
Line 7,995: | Line 7,817: | ||
In addition we provide Qt Simulator which allows you to quickly test and debug applications that target mobile devices. See the documentation on Qt Simulator http://doc.qt.io/qt-5/qtsimulator/simulator-description.html | In addition we provide Qt Simulator which allows you to quickly test and debug applications that target mobile devices. See the documentation on Qt Simulator http://doc.qt.io/qt-5/qtsimulator/simulator-description.html | ||
===How can I add a toolbar on a separate line?=== | ===How can I add a toolbar on a separate line?=== | ||
What you can do is call insertToolBarBreak() http://doc.qt.io/qt-5 | What you can do is call insertToolBarBreak() http://doc.qt.io/qt-5/qmainwindow.html#insertToolBarBreak or addToolBarBreak() http://doc.qt.io/qt-5/qmainwindow.html#addToolBarBreak on the QMainWindow when adding the toolbars, this will have the effect of a new line in the toolbar area and therefore the next toolbars added will be on that new line. | ||
Line 8,004: | Line 7,826: | ||
You can create a second pixmap, fill it with your background color, then draw the original pixmap on top. For example: | You can create a second pixmap, fill it with your background color, then draw the original pixmap on top. For example: | ||
< | <syntaxhighlight lang="cpp"> | ||
QPixmap filled(original.size()); | QPixmap filled(original.size()); | ||
QPainter paint(&filled); | QPainter paint(&filled); | ||
Line 8,010: | Line 7,832: | ||
paint.drawPixmap(0,0,original); | paint.drawPixmap(0,0,original); | ||
paint.end(); | paint.end(); | ||
</ | </syntaxhighlight> | ||
===What is the program qtusagereporter?=== | ===What is the program qtusagereporter?=== | ||
Line 8,020: | Line 7,842: | ||
If you do not have a special site licensing agreement withQt Development Frameworks, please feel free to delete the qtusagereporter file. | If you do not have a special site licensing agreement withQt Development Frameworks, please feel free to delete the qtusagereporter file. | ||
===Why is not the MySql driver loaded when running my application?=== | ===Why is not the MySql driver loaded when running my application?=== | ||
You need to make sure that everything has the same configuration. Make sure you have built your application, Qt and your plugin with the same configuration (i.e. debug vs release). Also, you need to make sure you have set your PATH environment variable to find the relevant MySql dll so that it can be found when the application runs. Alternatively, you can put the MySql dll (e.g libmysql.dll) in the same folder as the Qt dlls in yourQtDirectory/bin. | You need to make sure that everything has the same configuration. Make sure you have built your application, Qt and your plugin with the same configuration (i.e. debug vs release). Also, you need to make sure you have set your PATH environment variable to find the relevant MySql dll so that it can be found when the application runs. Alternatively, you can put the MySql dll (e.g libmysql.dll) in the same folder as the Qt dlls in yourQtDirectory/bin. | ||
===How can I have my widget resize when I hide a child widget in a layout?=== | ===How can I have my widget resize when I hide a child widget in a layout?=== | ||
In order to have a widget that resizes when you hide a child widget that is in a layout you need to first invalidate the layout that contains the child widget that was hidden and then call adjustSize() http://doc.qt.io/qt-5 | In order to have a widget that resizes when you hide a child widget that is in a layout you need to first invalidate the layout that contains the child widget that was hidden and then call adjustSize() http://doc.qt.io/qt-5/qwidget.html#adjustSize on the widget that contains that layout. If you have more parent widgets that contain that widget then you need to call adjustSize() on those too if you want to ensure that the top level widget adjusts to claim the space too. Something like: | ||
< | <syntaxhighlight lang="cpp"> | ||
widget->parentWidget()->layout()->invalidate(); | widget->parentWidget()->layout()->invalidate(); | ||
QWidget *parent = widget->parentWidget(); | QWidget *parent = widget->parentWidget(); | ||
Line 8,033: | Line 7,855: | ||
parent->adjustSize(); | parent->adjustSize(); | ||
parent = parent->parentWidget(); | parent = parent->parentWidget(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
where widget is the widget that has been hidden can be used generically to ensure that the top level widget adjusts to reclaim the space left by the hidden child widget. | where widget is the widget that has been hidden can be used generically to ensure that the top level widget adjusts to reclaim the space left by the hidden child widget. | ||
===How can I initialize the size of the central widget inside a QMainWindow?=== | ===How can I initialize the size of the central widget inside a QMainWindow?=== | ||
Line 8,048: | Line 7,870: | ||
receive the different activation events in Qt, the activation has already | receive the different activation events in Qt, the activation has already | ||
happened.You might be able to solve that by using the native API. | happened.You might be able to solve that by using the native API. | ||
===How can i get hold of all of the visible items in my QListView?=== | ===How can i get hold of all of the visible items in my QListView?=== | ||
In order to get hold of the visible items in a QListView http://doc.qt.io/qt-5 | In order to get hold of the visible items in a QListView http://doc.qt.io/qt-5/qlistview.html, then you can iterate over them using indexAt() http://doc.qt.io/qt-5/qlistview.html#indexAt. You can get hold of the first visible item using indexAt(QPoint(0, 0)), then in order to get the index at the next position then use visualRect() http://doc.qt.io/qt-5/qlistview.html#visualRect to find out what your next call to itemAt() should be. This position would be: | ||
< | <syntaxhighlight lang="cpp">visualRect.y() + visualRect.height() + 1 effectively.</syntaxhighlight> | ||
See the following example for an illustration: | See the following example for an illustration: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
QList <QModelIndex>myList; | QList <QModelIndex>myList; | ||
Line 8,076: | Line 7,898: | ||
void test1() | void test1() | ||
{ | { | ||
QModelIndex firstIndex = indexAt(QPoint(0, 0)); | QModelIndex firstIndex = indexAt(QPoint(0, 0)); | ||
if (firstIndex.isValid()) { | if (firstIndex.isValid()) { | ||
Line 8,099: | Line 7,921: | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I print a widget?=== | ===How can I print a widget?=== | ||
You can use QPixmap::grabWidget() http://doc.qt.io/qt-5/qpixmap.html#grabWidget to get a pixmap representation of the | You can use QPixmap::grabWidget() http://doc.qt.io/qt-5/qpixmap.html#grabWidget to get a pixmap representation of the | ||
widget. Since QPrinter is a paint device, you can open a painter on it directly and then draw this pixmap on to the printer. | widget. Since QPrinter is a paint device, you can open a painter on it directly and then draw this pixmap on to the printer. | ||
The example below illustrates how this can be done: | The example below illustrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Widget : public QWidget | class Widget : public QWidget | ||
Line 8,117: | Line 7,939: | ||
Widget() | Widget() | ||
{ | { | ||
QPushButton *button = new QPushButton(this); | |||
button->setText(Print me); | |||
QVBoxLayout *layout = new QVBoxLayout(this); | |||
layout->addWidget(button); | |||
connect(button, SIGNAL( clicked() ), this, SLOT(print() ) ); | |||
} | } | ||
public slots: | public slots: | ||
void print() | void print() | ||
{ | { | ||
QPrinter *printer = new QPrinter; | |||
QPrintDialog *printDialog = new QPrintDialog(printer, this); | |||
if (printDialog->exec() == QDialog::Accepted) { | |||
QPainter p(printer); | |||
QPixmap pm = QPixmap::grabWidget(this); | |||
p.drawPixmap(0, 0, pm); | |||
}}}; | |||
#include main.moc" | #include main.moc" | ||
Line 8,143: | Line 7,965: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I get debug output from my Qt applications?=== | ===How can I get debug output from my Qt applications?=== | ||
Line 8,151: | Line 7,973: | ||
stderr or stdout is not visible. You can add | stderr or stdout is not visible. You can add | ||
< | <syntaxhighlight lang="cpp">CONFIG += console</syntaxhighlight> | ||
to your .pro file (or modify the linker settings by changing /SUBSYSTEM:WINDOWS to /SUBSYSTEM:CONSOLE) to build a console-application, which runs attached to a console. | to your .pro file (or modify the linker settings by changing /SUBSYSTEM:WINDOWS to /SUBSYSTEM:CONSOLE) to build a console-application, which runs attached to a console. | ||
===How to deal correctly with project files that should generate a debug and release build=== | ===How to deal correctly with project files that should generate a debug and release build=== | ||
You need to add the following to your .pro file: | You need to add the following to your .pro file: | ||
< | <syntaxhighlight lang="cpp">CONFIG(debug, debug|release) { message(Debug build) } else { message(Release build) }</syntaxhighlight> | ||
This means that it will ensure that the debug stuff is processed when generating the debug version of the Makefile, and in the other case which is the release version, that the release stuff is processed. This enables you to specify specific options for debug and release builds. | This means that it will ensure that the debug stuff is processed when generating the debug version of the Makefile, and in the other case which is the release version, that the release stuff is processed. This enables you to specify specific options for debug and release builds. | ||
Line 8,165: | Line 7,987: | ||
Note that you should use the *build_pass* variable to filter out messages, otherwise you will get messages when it creates the Makefile which will be the configuration specific makefile. When adding the *build_pass* variable in conjunction with the following scope | Note that you should use the *build_pass* variable to filter out messages, otherwise you will get messages when it creates the Makefile which will be the configuration specific makefile. When adding the *build_pass* variable in conjunction with the following scope | ||
< | <syntaxhighlight lang="cpp">build_pass:CONFIG(debug, debug|release) { | ||
message(Debug build) | message(Debug build) | ||
} | } | ||
else:build_pass { | else:build_pass { | ||
message(Release build) | message(Release build) | ||
}</ | }</syntaxhighlight> | ||
the output will be as follows: | the output will be as follows: | ||
< | <syntaxhighlight lang="cpp">Project MESSAGE: Debug bulid | ||
Project MESSAGE: Release build</ | Project MESSAGE: Release build</syntaxhighlight> | ||
See the documentation: | See the documentation: | ||
http://doc.qt.io/qt-5/qmake-function-reference.html | http://doc.qt.io/qt-5/qmake-function-reference.html | ||
===How do I make a Qt application make a 'beep' sound?=== | ===How do I make a Qt application make a 'beep' sound?=== | ||
Call QApplication::beep() http://doc.troll.no/qapplication.html#beep | Call QApplication::beep() http://doc.troll.no/qapplication.html#beep | ||
===How can I instantiate new objects in my Qt Script code?=== | ===How can I instantiate new objects in my Qt Script code?=== | ||
To make it possible to instantiate QObjects in your script code you first need to use the Q_SCRIPT_DECLARE_QMETAOBJECT http://doc.qt.io/qt-5/qscriptengine.html#Q_SCRIPT_DECLARE_QMETAOBJECTmacro to declare your QMetaObject. Then make your class available as a QScriptValue http://doc.qt.io/qt-5 | To make it possible to instantiate QObjects in your script code you first need to use the Q_SCRIPT_DECLARE_QMETAOBJECT http://doc.qt.io/qt-5/qscriptengine.html#Q_SCRIPT_DECLARE_QMETAOBJECTmacro to declare your QMetaObject. Then make your class available as a QScriptValue http://doc.qt.io/qt-5/qscriptvalue.html by calling QScriptEngine::scriptValueFromMetaObject() QScriptEngine::scriptValueFromMetaObject(). See the documentation: | ||
See the following example for an illustration: | See the following example for an illustration: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include <QtScript> | #include <QtScript> | ||
#include < | #include <QtWidgets> | ||
Q_SCRIPT_DECLARE_QMETAOBJECT(QLineEdit, QWidget*) | Q_SCRIPT_DECLARE_QMETAOBJECT(QLineEdit, QWidget*) | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app (argc, argv); | QApplication app (argc, argv); | ||
QScriptEngine engine; | QScriptEngine engine; | ||
QScriptValue lineEditClass = engine.scriptValueFromQMetaObject<QLineEdit>(); | QScriptValue lineEditClass = engine.scriptValueFromQMetaObject<QLineEdit>(); | ||
engine.globalObject().setProperty("QLineEdit", lineEditClass); | engine.globalObject().setProperty("QLineEdit", lineEditClass); | ||
engine.evaluate("edit = new QLineEdit(0)"); | engine.evaluate("edit = new QLineEdit(0)"); | ||
engine.evaluate("edit.show()"); | engine.evaluate("edit.show()"); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===lupdate has problems translating classes which are using a namespace, how can I solve this ?=== | ===lupdate has problems translating classes which are using a namespace, how can I solve this ?=== | ||
C++ namespaces and the *using namespace* statement can confuse lupdate http://doc.qt.io/qt-5 | C++ namespaces and the *using namespace* statement can confuse lupdate http://doc.qt.io/qt-5/linguist-manager.html#lupdate. lupdate will interpret MyClass::tr()as meaning just that, not as MyNamespace::MyClass::tr(), even if MyClass is defined in the MyNamespace namespace. Runtime translation of these strings will fail because of that. You can solve this issue by adding a TRANSLATOR http://doc.qt.io/qt-5/linguist-programmers.html#coping-with-c-namespaces comment at the beginning of the source files that use MyClass::tr(). | ||
See the following example for a demonstration: | See the following example for a demonstration: | ||
< | <syntaxhighlight lang="cpp"> | ||
/* | /* | ||
TRANSLATOR myNamespace::Menu | TRANSLATOR myNamespace::Menu | ||
*/ | */ | ||
#include < | #include <QtWidgets> | ||
namespace myNamespace | namespace myNamespace | ||
{ | { | ||
class Menu : public QMenu | |||
{ | |||
Q_OBJECT | |||
public: | |||
Menu(QWidget *parent) : QMenu(parent) {} | |||
}; | |||
} | } | ||
Line 8,230: | Line 8,052: | ||
int main(int argc, char **argv) { | int main(int argc, char **argv) { | ||
using namespace myNamespace; | |||
QApplication a(argc, argv); | |||
QTranslator trans(0); | |||
trans.load(test_fr, .); | |||
a.installTranslator(&trans); | |||
QMainWindow w; | |||
Menu menu(&w); | |||
w.menuBar()->addMenu(&menu); | |||
menu.setTitle(Menu::tr(File)); | |||
QAction *fileAction = new QAction(QObject::tr(Item), 0); | |||
menu.addAction(fileAction); | |||
w.show(); | |||
return a.exec(); | |||
}</ | }</syntaxhighlight> | ||
===How can I insert a checkbox into the header of my view?=== | ===How can I insert a checkbox into the header of my view?=== | ||
Currently there is no API to insert widgets in the header, but you can paint the checkbox yourself in order to insert it into the header. | Currently there is no API to insert widgets in the header, but you can paint the checkbox yourself in order to insert it into the header. | ||
Line 8,253: | Line 8,075: | ||
The example below illustrates how this can be done: | The example below illustrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class MyHeader : public QHeaderView | class MyHeader : public QHeaderView | ||
{ | { | ||
public: | public: | ||
MyHeader(Qt::Orientation orientation, QWidget * parent = | MyHeader(Qt::Orientation orientation, QWidget * parent = nullptr) : QHeaderView(orientation, parent) | ||
{} | {} | ||
Line 8,266: | Line 8,088: | ||
{ | { | ||
painter->save(); | painter->save(); | ||
QHeaderView::paintSection(painter, rect, logicalIndex); | QHeaderView::paintSection(painter, rect, logicalIndex); | ||
painter->restore(); | painter->restore(); | ||
if (logicalIndex == 0) | if (logicalIndex == 0) | ||
Line 8,278: | Line 8,100: | ||
this->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter); | this->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter); | ||
} | } | ||
} | } | ||
void mousePressEvent(QMouseEvent *event) | void mousePressEvent(QMouseEvent *event) | ||
Line 8,284: | Line 8,106: | ||
if (isOn) | if (isOn) | ||
isOn = false; | isOn = false; | ||
else | else | ||
isOn = true; | isOn = true; | ||
this->update(); | this->update(); | ||
Line 8,302: | Line 8,124: | ||
MyHeader *myHeader = new MyHeader(Qt::Horizontal, &table); | MyHeader *myHeader = new MyHeader(Qt::Horizontal, &table); | ||
table.setHorizontalHeader(myHeader); | table.setHorizontalHeader(myHeader); | ||
table.show(); | table.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
To have all your other checkboxes checked, you could use the pressed() signal which should be fired from the mousePressEvent() http://doc.qt.io/qt-5/qheaderview.html#mousePressEvent and connect it to a custom slot where you set all your checkboxes checked or unchecked. See: | To have all your other checkboxes checked, you could use the pressed() signal which should be fired from the mousePressEvent() http://doc.qt.io/qt-5/qheaderview.html#mousePressEvent and connect it to a custom slot where you set all your checkboxes checked or unchecked. See: | ||
===I would like to add some widgets to a QMessageBox. How can I do it?=== | ===I would like to add some widgets to a QMessageBox. How can I do it?=== | ||
QMessageBox http://doc.qt.io/qt-5 | QMessageBox http://doc.qt.io/qt-5/qmessagebox.html is just a convenience class and does not offer this functionality. You will have to construct your own dialog. | ||
===Do you have integration with Xcode ?=== | ===Do you have integration with Xcode ?=== | ||
Line 8,321: | Line 8,143: | ||
create an Xcode project: | create an Xcode project: | ||
< | <syntaxhighlight lang="cpp"> qmake -spec macx-xcode project.pro</syntaxhighlight> | ||
See the documentation http://doc.qt.io/qt-5/qtmac-as-native.html#development-tools: | See the documentation http://doc.qt.io/qt-5/qtmac-as-native.html#development-tools: | ||
===Is it possible to change the language of Qt Assistant's GUI?=== | ===Is it possible to change the language of Qt Assistant's GUI?=== | ||
Qt Assistant will try to load a translation file called assistant_[locale].qm where [locale] is the locale as returned by QTextCodec::codecForlocale() http://doc.qt.io/qt-5 | Qt Assistant will try to load a translation file called assistant_[locale].qm where [locale] is the locale as returned by QTextCodec::codecForlocale() http://doc.qt.io/qt-5/qtextcodec.html#codecForLocale. So if you have your locale set to German, then assistant will try to load a file called assistant_de.qm. Qt comes with .ts files for both French and German for Assistant, if you want a different language then you can use one of the existing files as a base and provide new translations using Linguist http://doc.qt.io/qt-5/linguist-manual.html. | ||
===Does Qt provide translations for the user visible strings of the widgets?=== | ===Does Qt provide translations for the user visible strings of the widgets?=== | ||
Qt provides translation files for French, German and Simplified Chinese in $QTDIR/translations. This directory also contains some additional unsupported translations which may be useful, see: | Qt provides translation files for French, German and Simplified Chinese in $QTDIR/translations. This directory also contains some additional unsupported translations which may be useful, see: | ||
http://doc.qt.io/qt-5/internationalization.html | http://doc.qt.io/qt-5/internationalization.html | ||
These files contain translations for all of the classes in Qt that contain user visible strings and you can add them to your .pro file and follow the standard translation procedure to use them. In addition Qt provides a template for translating to other languages in qt_untranslated.ts | These files contain translations for all of the classes in Qt that contain user visible strings and you can add them to your .pro file and follow the standard translation procedure to use them. In addition Qt provides a template for translating to other languages in qt_untranslated.ts | ||
See the documentation for more information: | See the documentation for more information: | ||
http://doc.qt.io/qt-5/linguist-programmers.html | http://doc.qt.io/qt-5/linguist-programmers.html | ||
In addition we provide the lconvert tool which can be used to create an empty translation file so you can add your own translation for the Qt strings in a language that we don't provide for. To do this do: | In addition we provide the lconvert tool which can be used to create an empty translation file so you can add your own translation for the Qt strings in a language that we don't provide for. To do this do: | ||
lconvert --drop-translations -o qt_untranslated.ts qt_fr.ts | lconvert --drop-translations -o qt_untranslated.ts qt_fr.ts | ||
and then it will give you an empty translation file with the Qt strings ready to be translated. | and then it will give you an empty translation file with the Qt strings ready to be translated. | ||
===We would like to use Linguist with an MFC application, without converting MFC to Qt. Is this possible?=== | ===We would like to use Linguist with an MFC application, without converting MFC to Qt. Is this possible?=== | ||
Yes, but since the QObject http://doc.qt.io/qt-5 | Yes, but since the QObject http://doc.qt.io/qt-5/qobject.html class handles the translation, you will need to create a dll that has a function that basically calls QObject::tr() http://doc.qt.io/qt-5/qobject.html#tr and returns the result, making sure that you install the translators inside the code for the dll before using the function. You can use LoadLibrary in Windows API to load the library, then you just call the function via the dll. | ||
===Is there a way to remove the checkbox from a QTreeWidgetItem?=== | ===Is there a way to remove the checkbox from a QTreeWidgetItem?=== | ||
It is possible to remove the checbox from a QTreeWidgetItem http://doc.qt.io/qt-5 | It is possible to remove the checbox from a QTreeWidgetItem http://doc.qt.io/qt-5/qtreewidgetitem.html that has the Qt::ItemIsUserCheckable http://doc.qt.io/qt-5/qt.html#ItemFlag-enum flag set, simply by calling setData() http://doc.qt.io/qt-5/qtreewidgetitem.html#setData on the item with an invalid QVariant http://doc.qt.io/qt-5/qvariant.html, e.g | ||
< | <syntaxhighlight lang="cpp"> | ||
item->setData(0, Qt::CheckStateRole, QVariant()); | item->setData(0, Qt::CheckStateRole, QVariant()); | ||
</ | </syntaxhighlight> | ||
==="Why doesn't my keyboard work after I have done an export QWS_KEYBOARD=/dev/tty?"=== | ==="Why doesn't my keyboard work after I have done an export QWS_KEYBOARD=/dev/tty?"=== | ||
Try running the application without exporting QWS_KEYBOARD. The default value may be more appropriate than the value specified. | Try running the application without exporting QWS_KEYBOARD. The default value may be more appropriate than the value specified. | ||
===How can I implement my own proxy model that is more advanced than just sorting/filtering=== | ===How can I implement my own proxy model that is more advanced than just sorting/filtering=== | ||
Line 8,385: | Line 8,207: | ||
The example uses QStandardItemModel to simplify things on the source model side, but you can change the model in use on the source model and just tweak the fixModel() function to handle your own model instead. | The example uses QStandardItemModel to simplify things on the source model side, but you can change the model in use on the source model and just tweak the fixModel() function to handle your own model instead. | ||
===Mediaplayer demo program pauses before file is finished on embedded platform=== | ===Mediaplayer demo program pauses before file is finished on embedded platform=== | ||
Line 8,403: | Line 8,225: | ||
Again if you are not able to use GStreamer directly then you will not be able use it with Phonon. In this case you will need to contact your SDK provider or report a bug if needed to the GStreamer project: | Again if you are not able to use GStreamer directly then you will not be able use it with Phonon. In this case you will need to contact your SDK provider or report a bug if needed to the GStreamer project: | ||
https://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer | https://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer | ||
===How to improve graphics performance on X11=== | ===How to improve graphics performance on X11=== | ||
There are many factors that could be affecting the rendering of widgets under Qt. | There are many factors that could be affecting the rendering of widgets under Qt. | ||
A few things you can try in order of importance:- | A few things you can try in order of importance:- | ||
Line 8,417: | Line 8,239: | ||
4.See also the blogs series on Qt Graphics and Performance http://labs.trolltech.com/blogs/2010/01/11/qt-graphics-and-performance-the-cost-of-convenience. | 4.See also the blogs series on Qt Graphics and Performance http://labs.trolltech.com/blogs/2010/01/11/qt-graphics-and-performance-the-cost-of-convenience. | ||
===How can I get QMAKE_POST_LINK to work with more than one command on Windows?=== | ===How can I get QMAKE_POST_LINK to work with more than one command on Windows?=== | ||
When using multiple commands with QMAKE_POST_LINK e.g. | When using multiple commands with QMAKE_POST_LINK e.g. | ||
< | <syntaxhighlight lang="cpp">QMAKE_POST_LINK += copy ..\file.lib ..\..\lib\ | ||
QMAKE_POST_LINK += copy ..\file2.lib ..\..\lib\</ | QMAKE_POST_LINK += copy ..\file2.lib ..\..\lib\</syntaxhighlight> | ||
qmake tries to put them all on the same line, with the result that it fails to execute more than the first command. | qmake tries to put them all on the same line, with the result that it fails to execute more than the first command. | ||
Line 8,430: | Line 8,252: | ||
This was tested and functions correctly with nmake using the Microsoft build environment. | This was tested and functions correctly with nmake using the Microsoft build environment. | ||
===How do I remove qtmain.lib from the Qt build?=== | ===How do I remove qtmain.lib from the Qt build?=== | ||
To remove this, you can define *QMAKE_LIBS_QT_ENTRY* as empty in your .pro file like this: | To remove this, you can define *QMAKE_LIBS_QT_ENTRY* as empty in your .pro file like this: | ||
< | <syntaxhighlight lang="cpp">QMAKE_LIBS_QT_ENTRY=</syntaxhighlight> | ||
===How can my stylesheet account for custom properties?=== | ===How can my stylesheet account for custom properties?=== | ||
Line 8,444: | Line 8,266: | ||
http://doc.qt.io/qt-5/stylesheet-examples.html#customizing-using-dynamic-properties | http://doc.qt.io/qt-5/stylesheet-examples.html#customizing-using-dynamic-properties | ||
If the value of the Qt property changes after the style sheet has been set, you will probably have to force a style sheet recomputation. This can be done by calling | If the value of the Qt property changes after the style sheet has been set, you will probably have to force a style sheet recomputation. This can be done by calling | ||
< | <syntaxhighlight lang="cpp"> | ||
style()->unpolish(theWidget); | style()->unpolish(theWidget); | ||
style()->polish(theWidget); | style()->polish(theWidget); | ||
</ | </syntaxhighlight> | ||
Alternatively, you can unset the style sheet and set it again, but this is more expensive than the first solution. | Alternatively, you can unset the style sheet and set it again, but this is more expensive than the first solution. | ||
The following example demonstrates how this can be done: | The following example demonstrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class LineEdit : public QLineEdit | class LineEdit : public QLineEdit | ||
Line 8,498: | Line 8,320: | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I set headers for a QColumnView?=== | ===How can I set headers for a QColumnView?=== | ||
Line 8,505: | Line 8,327: | ||
In the QColumnView-model definition, we define the UserRole: | In the QColumnView-model definition, we define the UserRole: | ||
< | <syntaxhighlight lang="cpp"> | ||
enum UserRole { HeaderRole = Qt::UserRole + 1 }; | enum UserRole { HeaderRole = Qt::UserRole + 1 }; | ||
</ | </syntaxhighlight> | ||
And in the model-declaration, we set the header-data on the custom HeaderRole: | And in the model-declaration, we set the header-data on the custom HeaderRole: | ||
< | <syntaxhighlight lang="cpp"> | ||
QStandardItemModel * model = new QStandardItemModel(); | QStandardItemModel * model = new QStandardItemModel(); | ||
QStandardItem * | QStandardItem * root = model->invisibleRootItem(); | ||
root = model->invisibleRootItem(); | |||
QStandardItem * item = new QStandardItem(QString("single %1").arg(i)); | QStandardItem * item = new QStandardItem(QString("single %1").arg(i)); | ||
root->appendRow(item); | root->appendRow(item); | ||
item->setData(tr("Header A 1"), CustomColumnView::HeaderRole); | item->setData(tr("Header A 1"), CustomColumnView::HeaderRole); | ||
</ | </syntaxhighlight> | ||
The header is then painted in the reimplemented paintEvent() http://doc.qt.io/qt-5 | The header is then painted in the reimplemented paintEvent() http://doc.qt.io/qt-5/qheaderview.html#paintEvent function of the QHeaderView class. | ||
===Why do I get an error when trying to set a model on QTableWidget?=== | ===Why do I get an error when trying to set a model on QTableWidget?=== | ||
QTableWidget http://doc.qt.io/qt-5 | QTableWidget http://doc.qt.io/qt-5/qtablewidget.html already comes with a model, so you can't set your own model on it. The reimplementation of QTableWidget::setModel() http://doc.qt.io/qt-5/qtableview.html#setModel in qtablewidget.cpp looks like this: | ||
< | <syntaxhighlight lang="cpp"> | ||
void QTableWidget::setModel(QAbstractItemModel * /*model*/) | void QTableWidget::setModel(QAbstractItemModel * /*model*/) | ||
{ | { | ||
Line 8,531: | Line 8,352: | ||
} | } | ||
</ | </syntaxhighlight> | ||
So, if you want to use your own model, you need to use a QTableView http://doc.qt.io/qt-5 | So, if you want to use your own model, you need to use a QTableView http://doc.qt.io/qt-5/qtableview.html instead of the QTableWidget convenience class and set the model on that one. | ||
===How can I create editable headers in a QTableView?=== | ===How can I create editable headers in a QTableView?=== | ||
QTableView http://doc.qt.io/qt-5 | QTableView http://doc.qt.io/qt-5/qtableview.html is not designed to have editable headers. | ||
A solution to achieve this can be done with a QLineEdit http://doc.qt.io/qt-5 | A solution to achieve this can be done with a QLineEdit http://doc.qt.io/qt-5/qlineedit.html. The idea is to create an edit box over the expected header section and make it behave like an usual cell when edited. | ||
The example below illustrates this approach. | The example below illustrates this approach. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class MyEditHeaderBox : public QLineEdit | class MyEditHeaderBox : public QLineEdit | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
MyEditHeaderBox(QWidget *parent =0) | |||
: QLineEdit(parent) | |||
{ | |||
QValidator *validator = new QDoubleValidator(this); | |||
setValidator(validator); | |||
setFocusPolicy(Qt::StrongFocus); | |||
connect(this, SIGNAL(returnPressed()), this, SLOT(headerValue())); | |||
} | |||
void setLabelValue(Qt::Orientation orientation, int section, QString value) | |||
{ | |||
setText(value); | |||
curOrientation = orientation; | |||
curSection = section; | |||
} | |||
protected slots: | |||
void headerValue() | |||
{ | |||
double value = text().toDouble(); | |||
emit updateHeader(value, curSection, curOrientation); | |||
} | |||
signals: | signals: | ||
void updateHeader(double newValue, int section, Qt::Orientation o); | |||
protected: | protected: | ||
void keyPressEvent ( QKeyEvent * ev ) | |||
{ | |||
if (ev->key() == Qt::Key_Escape) | |||
{ | |||
hide(); | |||
} | |||
QLineEdit::keyPressEvent(ev); | |||
} | |||
void focusOutEvent ( QFocusEvent * event ) | |||
{ | |||
hide(); | |||
QLineEdit::focusOutEvent(event); | |||
} | |||
private: | private: | ||
Qt::Orientation curOrientation; | |||
int curSection; | |||
}; | }; | ||
Line 8,600: | Line 8,421: | ||
class MyMainWindow : public QMainWindow | class MyMainWindow : public QMainWindow | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
MyMainWindow(QWidget *parent = nullptr) | |||
: QMainWindow(parent), border(1) | |||
{ | |||
view = new QTableView(this); | |||
int nbPoints = 5; | |||
model = new QStandardItemModel(nbPoints, nbPoints, this); | |||
for (int r = 0; r < nbPoints; r++) { | |||
for (int c = 0; c < nbPoints; c++) { | |||
QStandardItem *item = new QStandardItem; | |||
item->setData((r+1)*(c+1), Qt::DisplayRole); | |||
model->setItem(r,c,item); | |||
} | |||
} | |||
view->setModel(model); | |||
le = new MyEditHeaderBox(this); | |||
le->hide(); | |||
connect(view->horizontalHeader(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(xHeader(int))); | |||
connect(view->verticalHeader(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(yHeader(int))); | |||
setCentralWidget(view); | |||
resize(550,300); | |||
} | |||
protected slots: | |||
void xHeader(int section) | |||
{ | |||
QPoint posHeaderX = QPoint(view->horizontalHeader()->geometry().x(), view->horizontalHeader()->geometry().y()); | |||
QPoint posView = this->pos() + QPoint(view->geometry().x(), view->geometry().y()); | |||
QPoint posSection = QPoint(view->horizontalHeader()->sectionPosition(section),-border); | |||
showHeaderEditBox(section, Qt::Horizontal, QRect(posSection + posHeaderX , QSize(view->horizontalHeader()->sectionSize(section),view->horizontalHeader()->height()))); | |||
} | |||
void yHeader(int section) | |||
{ | |||
QPoint posHeaderY = QPoint(view->verticalHeader()->geometry().x(), view->verticalHeader()->geometry().y()); | |||
QPoint posView = this->pos() + QPoint(view->geometry().x(), view->geometry().y()); | |||
QPoint posSection = QPoint(0, view->verticalHeader()->sectionPosition(section)-border); | |||
showHeaderEditBox(section, Qt::Vertical, QRect(posSection + posHeaderY, QSize(view->verticalHeader()->width(), view->verticalHeader()->sectionSize(section)))); | |||
} | |||
void updateData(double newValue, int section, Qt::Orientation orientation) | |||
{ | |||
view->model()->setHeaderData(section, orientation, newValue, Qt::DisplayRole); | |||
le->hide(); | |||
} | |||
protected: | protected: | ||
void showHeaderEditBox(int section, Qt::Orientation orientation, QRect rectSection) | |||
{ | |||
QString curValue = QVariant(view->model()->headerData(section, orientation, Qt::DisplayRole)).toString(); | |||
le->setGeometry(rectSection); | |||
le->setLabelValue(orientation, section, curValue); | |||
connect(le, SIGNAL(updateHeader(double,int,Qt::Orientation)), this, SLOT(updateData(double, int, Qt::Orientation))); | |||
le->show(); | |||
le->setFocus(); | |||
le->selectAll(); | |||
} | |||
private: | private: | ||
QTableView *view; | |||
MyEditHeaderBox *le; | |||
QStandardItemModel *model; | |||
int border; | |||
}; | }; | ||
Line 8,683: | Line 8,504: | ||
int main(int argc, char *argv[]) | int main(int argc, char *argv[]) | ||
{ | { | ||
QApplication a(argc, argv); | |||
MyMainWindow w; | |||
w.show(); | |||
return a.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
===How can the user be prevented from assigning to an undeclared variable in Qt Script?=== | ===How can the user be prevented from assigning to an undeclared variable in Qt Script?=== | ||
To let the script engine know if an undeclared variable has been assigned, e.g in the following scenario: | To let the script engine know if an undeclared variable has been assigned, e.g in the following scenario: | ||
< | <syntaxhighlight lang="cpp"> | ||
function testClass() | function testClass() | ||
{ | { | ||
this.someProperty = "test"; | this.someProperty = "test"; | ||
} | } | ||
{ | { | ||
... | ... | ||
a_class = new myClass; | a_class = new myClass; | ||
Line 8,705: | Line 8,526: | ||
a_class.SomeProperty = "assigned"; | a_class.SomeProperty = "assigned"; | ||
... | ... | ||
} </ | } </syntaxhighlight> | ||
then you can use one of the following approaches. | then you can use one of the following approaches. | ||
# For QObjects http://doc.qt.io/qt-5 | # For QObjects http://doc.qt.io/qt-5/qobject.html then the most flexible approach would be to inherit from QScriptClass http://doc.qt.io/qt-5/qscriptclass.html so that you can control individual property access (read/write) yourself and e.g through an exception (QScriptContext::throwError() http://doc.qt.io/qt-5/qscriptcontext.html#throwError) when an incorrect property gets assigned. | ||
# For QObjects, you can send along QScriptEngine::AutoCreateDynamicProperties() http://doc.qt.io/qt-5 | # For QObjects, you can send along QScriptEngine::AutoCreateDynamicProperties() http://doc.qt.io/qt-5/qscriptengine.html#QObjectWrapOption-enum to newQObject() http://doc.qt.io/qt-5/qscriptengine.html#newObject, and listen for DynamicPropertyChangeEvent http://doc.qt.io/qt-5/qevent.html#Type-enum to find out when a property that does not exist in the metaobject gets assigned. | ||
When using normal JS-objects it is not possible to detect this. In Ecmascript 5 there is a new function Object.seal() that makes it impossible to add new properties, but it is not supported by JavaScriptCore (the Javascript engine used by QtScript) yet. | When using normal JS-objects it is not possible to detect this. In Ecmascript 5 there is a new function Object.seal() that makes it impossible to add new properties, but it is not supported by JavaScriptCore (the Javascript engine used by QtScript) yet. | ||
===Why is the fragment removed when using QDesktopServices::openUrl() to open a local file url with a fragment?=== | ===Why is the fragment removed when using QDesktopServices::openUrl() to open a local file url with a fragment?=== | ||
When opening a local file url with a fragment using QDesktopServices::openUrl() http://doc.qt.io/qt-5 | When opening a local file url with a fragment using QDesktopServices::openUrl() http://doc.qt.io/qt-5/qdesktopservices.html#openUrl then the fragment will not be shown due to a Windows limiation. A url containing the following string for example | ||
.../extensionsystem-pluginview.html#pluginActivated" | .../extensionsystem-pluginview.html#pluginActivated" | ||
Line 8,725: | Line 8,546: | ||
.../extensionsystem-pluginview.html | .../extensionsystem-pluginview.html | ||
part. This is because Windows operates on files, and the fragment part (#pluginActivated in the example above) breaks the file name handling. Note that if you want to provide help documentation for your application, then the recommended way of providing help documentation with Qt is to use Qt Assistant http://doc.qt.io/qt-5 | part. This is because Windows operates on files, and the fragment part (#pluginActivated in the example above) breaks the file name handling. Note that if you want to provide help documentation for your application, then the recommended way of providing help documentation with Qt is to use Qt Assistant http://doc.qt.io/qt-5/assistant-manual.html. Qt Assistant can use HTML source and make it viewable through assistant. The documentation http://doc.qt.io/qt-5/assistant-custom-help-viewer.html gives you more details. | ||
===How can I change the timeout period for a QToolTip?=== | ===How can I change the timeout period for a QToolTip?=== | ||
The tooltip delay is currently hardcoded in the implementation of QApplication::notify() http://doc.qt.io/qt-5 | The tooltip delay is currently hardcoded in the implementation of QApplication::notify() http://doc.qt.io/qt-5/qapplication.html#notify, so it is not possible to modify it directly. What you can do however is to send a QHelpEvent() http://doc.qt.io/qt-5/qhelpevent.html when the mouse hovers over your widget. Then you can show the tooltip using QToolTip::showText() http://doc.qt.io/qt-5/qtooltip.html#showText in your event handler and set up a timer that calls QToolTip::hideText() http://doc.qt.io/qt-5/qtooltip.html#hideText after the amount of time that you would like. | ||
The example below illustrates how this can be done. | The example below illustrates how this can be done. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class myButton :public QPushButton | class myButton :public QPushButton | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
myButton() | |||
{ | |||
firstTime = true; | |||
setMouseTracking(true); | |||
} | |||
bool event(QEvent *event) | |||
{ | |||
if (event->type() == QEvent::ToolTip) { | |||
firstTime = false; | |||
QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event); | |||
QString myToolTip=ToolTip for a button ; | |||
QToolTip::showText(helpEvent->globalPos(),myToolTip ); | |||
QTimer::singleShot(4000, this, SLOT(testSlot())); | |||
} | |||
return QWidget::event(event); | |||
} | |||
void mouseMoveEvent(QMouseEvent *e) | |||
{ | |||
QPushButton::mouseMoveEvent(e); | |||
mousePosition = e->globalPos(); | |||
} | |||
void leaveEvent(QEvent *myLeave) | |||
{ | |||
QPushButton::leaveEvent(myLeave); | |||
firstTime = true; | |||
} | |||
public slots: | |||
void testSlot() | |||
{ | |||
QToolTip::hideText(); | |||
} | |||
public: | public: | ||
QPoint mousePosition; | |||
bool firstTime; | |||
}; | }; | ||
class myWidget :public QWidget | class myWidget :public QWidget | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
myWidget(QWidget *parent=0):QWidget(parent) | |||
{ | |||
but = new myButton; | |||
but->setText(Hello:); | |||
QVBoxLayout *layout = new QVBoxLayout; | |||
setLayout(layout); | |||
layout->addWidget(but); | |||
QTimer *timer = new QTimer(this); | |||
connect(timer, SIGNAL(timeout()), this, SLOT(myEventSender())); | |||
timer->start(1000); | |||
} | |||
public slots: | |||
void myEventSender() | |||
{ | |||
if(but->underMouse() && but->firstTime) | |||
{ | |||
QHelpEvent e(QEvent::ToolTip, but->pos(), but->mousePosition); | |||
QApplication::sendEvent(but, &e); | |||
} | |||
} | |||
public: | public: | ||
myButton *but; | |||
}; | }; | ||
#include main.moc" | #include main.moc" | ||
Line 8,812: | Line 8,633: | ||
int main(int argc,char *argv[]) | int main(int argc,char *argv[]) | ||
{ | { | ||
QApplication app(argc,argv); | |||
myWidget widget; | |||
widget.show(); | |||
return app.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I make my Qt application use wchar_t instead of wchar_t- ?=== | ===How can I make my Qt application use wchar_t instead of wchar_t- ?=== | ||
You need to configure Qt with wchar_t enabled as wchar_t- is enabled by default. So go to yourQtVersion/mkspecs/yourMkspec/qmake.conf and change the wchar_t- option to wchar_t and reconfigure and rebuild Qt and your application. This should ensure that wchar_t is treated as built-in type. | You need to configure Qt with wchar_t enabled as wchar_t- is enabled by default. So go to yourQtVersion/mkspecs/yourMkspec/qmake.conf and change the wchar_t- option to wchar_t and reconfigure and rebuild Qt and your application. This should ensure that wchar_t is treated as built-in type. | ||
===How can I create a QSettings group that is sorted numerically?=== | ===How can I create a QSettings group that is sorted numerically?=== | ||
QSettings http://doc.qt.io/qt-5 | QSettings http://doc.qt.io/qt-5/qsettings.html uses a QMap http://doc.qt.io/qt-5/qmap.html underneath to store the items, and a QMap is always sorted alphabetically. There is nothing you can do to change that to a numerical sorting. What you can do however is to handle this yourself by registering your own format, then you can pass in your own functions that will read and write QSettings key/value pairs the way you want, see: | ||
http://doc.qt.io/qt-5/qsettings.html#registerFormat | http://doc.qt.io/qt-5/qsettings.html#registerFormat | ||
===How can I display a tooltip over only one word in a QLabel?=== | ===How can I display a tooltip over only one word in a QLabel?=== | ||
It is hard to achieve this with a QLabel http://doc.qt.io/qt-5 | It is hard to achieve this with a QLabel http://doc.qt.io/qt-5/qlabel.html since there is no direct API for determining when the mouse is over the individual words in the QLabel. What you can do instead however, is to create a QTextEdit http://doc.qt.io/qt-5/qtextedit.html that looks like a QLabel. Then you can reimplement event() http://doc.qt.io/qt-5/qabstractscrollarea.html#event and listen for the QEvent::ToolTip http://doc.qt.io/qt-5/qevent.html#Type-enum event and use QTextEdit::cursorForPosition() http://doc.qt.io/qt-5/qtextedit.html#cursorForPosition and QTextCursor::select(QTextCursor::WordUnderCursor) to check the word that's under the cursor. | ||
See the documentation: | See the documentation: | ||
Line 8,841: | Line 8,662: | ||
The following example illustrates how this can be done. | The following example illustrates how this can be done. | ||
< | <syntaxhighlight lang="cpp">#include <QtWidgets> | ||
class TextEdit : public QTextEdit | class TextEdit : public QTextEdit | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
TextEdit(QWidget *parent) : QTextEdit(parent) | |||
{ | |||
setTextInteractionFlags(Qt::TextBrowserInteraction); | |||
setFrameStyle(QFrame::NoFrame); | |||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); | |||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); | |||
setText(This application only provides a tooltip for the following word: polymorphism); | |||
QPalette pal = palette(); | |||
pal.setColor(QPalette::Base, QColor(1, 0.941176, 0.941176, 0.941176) ); | |||
setReadOnly(true); | |||
setPalette(pal); | |||
setFixedHeight(18); | |||
setFixedWidth(400); | |||
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); | |||
} | |||
bool event(QEvent* event) { | |||
if (event->type() == QEvent::ToolTip) | |||
{ | |||
QHelpEvent* helpEvent = static_cast <QHelpEvent*>(event); | |||
QTextCursor cursor = cursorForPosition(helpEvent->pos()); | |||
cursor.select(QTextCursor::WordUnderCursor); | |||
if (cursor.selectedText() == polymorphism) | |||
QToolTip::showText(helpEvent->globalPos(), cursor.selectedText()); | |||
else | |||
QToolTip::hideText(); | |||
return true; | |||
} | |||
return QTextEdit::event(event); | |||
} | |||
void scrollContentsBy ( int dx, int dy ) | |||
{ | |||
} | |||
}; | }; | ||
Line 8,889: | Line 8,710: | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
QWidget wid; | |||
TextEdit *edit = new TextEdit(&wid); | |||
TextEdit *edit2 = new TextEdit(&wid); | |||
QVBoxLayout *layout = new QVBoxLayout(&wid); | |||
layout->addWidget(edit); | |||
layout->addWidget(edit2); | |||
wid.show(); | |||
return app.exec(); | |||
}</syntaxhighlight> | |||
===How can I convert a colored QPixmap into a grayscaled QPixmap?=== | ===How can I convert a colored QPixmap into a grayscaled QPixmap?=== | ||
Line 8,907: | Line 8,728: | ||
The following example illustrates how this can be done: | The following example illustrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
Line 8,933: | Line 8,754: | ||
label.show(); | label.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Why do I get the following error: QtMain.lib(qtmain_win.obj) : fatal error LNK1103: debugging information corrupt; recompile module?=== | ===Why do I get the following error: QtMain.lib(qtmain_win.obj) : fatal error LNK1103: debugging information corrupt; recompile module?=== | ||
This error can occur when downloading the wrong binary package, e.g when downloading qt-win-commercial-4.6.3-vs2008.exe and using it with Visual Studio 2005, so make sure you have downloaded the correct package. | This error can occur when downloading the wrong binary package, e.g when downloading qt-win-commercial-4.6.3-vs2008.exe and using it with Visual Studio 2005, so make sure you have downloaded the correct package. | ||
This error can also occur when having 2 compilers installed and not using the same compiler that was used for building the package. In this case, you need to ensure that your environment is set up correctly for the compiler you want to use. If you have installed the binary package for VS 2008 for example, you need to use it with the VS 2008 compiler. In order to do so, then use the command prompt provided with the binary package or select the Visual Studio with Qt SomeVersion option in the Start menu. | This error can also occur when having 2 compilers installed and not using the same compiler that was used for building the package. In this case, you need to ensure that your environment is set up correctly for the compiler you want to use. If you have installed the binary package for VS 2008 for example, you need to use it with the VS 2008 compiler. In order to do so, then use the command prompt provided with the binary package or select the Visual Studio with Qt SomeVersion option in the Start menu. | ||
Line 8,943: | Line 8,764: | ||
You can check if the correct compiler is set up in your environment, by typing | You can check if the correct compiler is set up in your environment, by typing | ||
< | <syntaxhighlight lang="cpp">set</syntaxhighlight> | ||
in the command prompt provided with the binary package. Then you need to make sure the compiler you want to use is listed first in your PATH environment variable. | in the command prompt provided with the binary package. Then you need to make sure the compiler you want to use is listed first in your PATH environment variable. | ||
Line 8,949: | Line 8,770: | ||
Alternatively, you can use the command prompts provided with Visual Studio and call | Alternatively, you can use the command prompts provided with Visual Studio and call | ||
< | <syntaxhighlight lang="cpp">set qmakespec=theMkSpecYouUse | ||
PATH=%path%;yourQtVersion/bin;</ | PATH=%path%;yourQtVersion/bin;</syntaxhighlight> | ||
to make sure you use the Qt version built with that compiler. | to make sure you use the Qt version built with that compiler. | ||
==="When creating a custom library on Winows and trying to use it in my application, then why do I get the error cannot open file ��yLibrary.lib?"=== | ==="When creating a custom library on Winows and trying to use it in my application, then why do I get the error cannot open file ��yLibrary.lib?"=== | ||
Line 8,963: | Line 8,784: | ||
The reason you get this error is because qmake can't locate the header files for the Postgres client. You need to ensure that the Postgres client include files are added to the environment, for example by adding them to the INCLUDE environment variable or to the INCLUDEPATH in the .profile. Note that if the header files exist in a directory with spaces in it, you need to quote the path since qmake does not support paths with spaces in them, e.g: | The reason you get this error is because qmake can't locate the header files for the Postgres client. You need to ensure that the Postgres client include files are added to the environment, for example by adding them to the INCLUDE environment variable or to the INCLUDEPATH in the .profile. Note that if the header files exist in a directory with spaces in it, you need to quote the path since qmake does not support paths with spaces in them, e.g: | ||
< | <syntaxhighlight lang="cpp"> INCLUDEPATH+=$$quote(c:\program files......)</syntaxhighlight> | ||
Similarly, you need to add the library files to the LIB environment variable or the LIBS variable in the .pro file. | Similarly, you need to add the library files to the LIB environment variable or the LIBS variable in the .pro file. | ||
===How can I use several Qt based dlls in an external application?=== | ===How can I use several Qt based dlls in an external application?=== | ||
Line 8,975: | Line 8,796: | ||
* export the dlls using __declspec(dllexport) | * export the dlls using __declspec(dllexport) | ||
* if your Qt based dlls depend on different versions of Qt, you need to ensure that the right ones are picked up for each dll by configuring Qt with the qtlibinfix and namespace options http://doc.qt.io/qt-5 | * if your Qt based dlls depend on different versions of Qt, you need to ensure that the right ones are picked up for each dll by configuring Qt with the qtlibinfix and namespace options http://doc.qt.io/qt-5/configure-options.html to ensure that each dll has a unique name and to avoid symbol conflicts: | ||
<syntaxhighlight lang="cpp">configure -qtlibinfix customName -qtnamespace theNamespace</syntaxhighlight> | |||
===How can I create a 3rd party plugin using Qt that performs event handling?=== | ===How can I create a 3rd party plugin using Qt that performs event handling?=== | ||
When creating a 3rd party Qt plugin/library that performs event handling, then you need to have an eventloop running that takes care of the event handling for you. This can be done in three ways: | When creating a 3rd party Qt plugin/library that performs event handling, then you need to have an eventloop running that takes care of the event handling for you. This can be done in three ways: | ||
1) You can instantiate a QCoreApplication/QApplication instance and call exec() http://doc.qt.io/qt-5 | 1) You can instantiate a QCoreApplication/QApplication instance and call exec() http://doc.qt.io/qt-5/qcoreapplication.html#exec on it to start the event handling and call quit() http://doc.qt.io/qt-5/qcoreapplication.html#quit when the plugin unloads. Using this approach, the rest of the application will be blocked as long as the event loop is running. | ||
2) You can call processEvents() http://doc.qt.io/qt-5 | 2) You can call processEvents() http://doc.qt.io/qt-5/qcoreapplication.html#processEvents on the application periodically and with the help of timers control the event handling yourself. Using this approach, the plugin will still block, but only until there are no more events to process, which allows you to go back to the main application. In addition you have control over when these events should be processed. | ||
3) Your Non-Gui Qt objects can reside in a worker thread that has an event loop in it to avoid having to call exec()/processevents() on the application. The event loop can be started by calling QThread::exec() http://doc.qt.io/qt-5/qthread.html#exec. | 3) Your Non-Gui Qt objects can reside in a worker thread that has an event loop in it to avoid having to call exec()/processevents() on the application. The event loop can be started by calling QThread::exec() http://doc.qt.io/qt-5/qthread.html#exec. | ||
Line 8,994: | Line 8,815: | ||
http://doc.qt.io/qt-5/threads-qobject.html#signals-and-slots-across-threads | http://doc.qt.io/qt-5/threads-qobject.html#signals-and-slots-across-threads | ||
===What is the difference between the QPSQL7 and QPSQL drivers?=== | ===What is the difference between the QPSQL7 and QPSQL drivers?=== | ||
There is not really a difference between the QPSQL7 and QPSQL drivers. QPSQL7 is there for compatibility with Qt 3, so it is best to use QPSQL. It would make no actual difference if you used QPSQL7 though. | There is not really a difference between the QPSQL7 and QPSQL drivers. QPSQL7 is there for compatibility with Qt 3, so it is best to use QPSQL. It would make no actual difference if you used QPSQL7 though. | ||
===Why do I get linking errors issued from moc when building my project?=== | ===Why do I get linking errors issued from moc when building my project?=== | ||
Errors like the following: | Errors like the following: | ||
< | <syntaxhighlight lang="cpp">Error 1 error LNK2001: unresolved external symbol public: virtual struct QMetaObject const * __thiscall myApp_qt::metaObject(void)const (?metaObject@myApp@@UBEPBUQMetaObject@@XZ) myApp.obj myApp)</syntaxhighlight> | ||
are typically issued by the moc http://doc.qt.io/qt-5/moc.html#moc preprocessor and indicate that there is no moc-generated cpp file, or the moc-generated cpp-file is not compiled and linked into your project. | are typically issued by the moc http://doc.qt.io/qt-5/moc.html#moc preprocessor and indicate that there is no moc-generated cpp file, or the moc-generated cpp-file is not compiled and linked into your project. | ||
You can try regenerating the .vcproj file on the command line to see if this helps. This can have an effect in situations where the .vcproj file has not been updated with information about the moc file. Open the command prompt provided with Qt in the Start menu and you go to your project's directory and type | You can try regenerating the .vcproj file on the command line to see if this helps. This can have an effect in situations where the .vcproj file has not been updated with information about the moc file. Open the command prompt provided with Qt in the Start menu and you go to your project's directory and type | ||
< | <syntaxhighlight lang="cpp">qmake -tp vc | ||
devenv yourProject.vcproj</ | devenv yourProject.vcproj</syntaxhighlight> | ||
to see if that helps. | to see if that helps. | ||
Line 9,016: | Line 8,837: | ||
The attached projects demonstrate the 2 possible ways of linking the moc generated code with your application. In the single main.cpp, the class declaration is in the .cpp file and we need to include the moc generated file into the application by adding the following line: | The attached projects demonstrate the 2 possible ways of linking the moc generated code with your application. In the single main.cpp, the class declaration is in the .cpp file and we need to include the moc generated file into the application by adding the following line: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include "nameOfFile.moc" | #include "nameOfFile.moc" | ||
</ | </syntaxhighlight> | ||
In the .zip file, the class declaration is in the .h file and the moc output will then be put in a file called moc_myclass.cpp. This file should be compiled and linked as normal. | In the .zip file, the class declaration is in the .h file and the moc output will then be put in a file called moc_myclass.cpp. This file should be compiled and linked as normal. | ||
===Can I use _CrtMemCheckpoint, _CrtMemDifference and friends to look for memory leaks in my Qt application?=== | ===Can I use _CrtMemCheckpoint, _CrtMemDifference and friends to look for memory leaks in my Qt application?=== | ||
Line 9,027: | Line 8,848: | ||
Instead we recommend using Purify or Boundschecker on Windows. | Instead we recommend using Purify or Boundschecker on Windows. | ||
===What is needed for deploying a Phonon based application?=== | ===What is needed for deploying a Phonon based application?=== | ||
Line 9,040: | Line 8,861: | ||
* QtOpenGL4.dll | * QtOpenGL4.dll | ||
* phonon_backend (directory) | * phonon_backend (directory) | ||
It is necessary to copy the QtOpenGL4.dll since the phonon backend relies on this on Windows. The folder named phonon_backend above needs to contain the following file: | It is necessary to copy the QtOpenGL4.dll since the phonon backend relies on this on Windows. The folder named phonon_backend above needs to contain the following file: | ||
Line 9,051: | Line 8,872: | ||
instead of the Visual Studio Redistributable Package. | instead of the Visual Studio Redistributable Package. | ||
===When clicking a custom item delegate, how can I ensure that its row gets selected in the QTableView?=== | ===When clicking a custom item delegate, how can I ensure that its row gets selected in the QTableView?=== | ||
You need to ensure that whenever a mouse event occurs on a widget that you programatically select the row underneath it as the QTableView http://doc.qt.io/qt-5 | You need to ensure that whenever a mouse event occurs on a widget that you programatically select the row underneath it as the QTableView http://doc.qt.io/qt-5/qtableview.html itself will not be getting the mouse event. The problem with this is that you need to have some way of tying in the widget to a row so that you know which row to call select() for. In the attached example a map is used to connect a widget to a row. The delegate's eventFilter() http://doc.qt.io/qt-5/qstyleditemdelegate.html#eventFilter is reimplemented and installed on the widgets, so that whenever a mouse press occurs, the event filter emits a signal causing the row to be selected. | ||
In addition QStyledItemDelegate::paint() http://doc.qt.io/qt-5 | In addition QStyledItemDelegate::paint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#paint is reimplemented. This is necessary because when clicking on a widget, it takes focus and the table will then not be the active widget and hence show an inactive selection. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include | #include | ||
<QtGui> | <QtGui> | ||
Line 9,065: | Line 8,886: | ||
class MyStyledItemDelegate : public QStyledItemDelegate | class MyStyledItemDelegate : public QStyledItemDelegate | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
MyStyledItemDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {} | |||
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const | |||
{ | |||
QWidget *w = new QWidget(parent); | |||
QLineEdit *le = new QLineEdit(w); | |||
le->installEventFilter((QObject *)this); | |||
MyStyledItemDelegate *that = (MyStyledItemDelegate *)this; | |||
that->rowMap.insert(w, index.row()); | |||
return w; | |||
} | |||
bool eventFilter(QObject *object, QEvent *event) | |||
{ | |||
bool ret = QStyledItemDelegate::eventFilter(object, event); | |||
if (event->type() == QEvent::MouseButtonPress) { | |||
QWidget *w = (QWidget *)object; | |||
int row = rowMap.value(w, -1); | |||
while (row == -1 && w) { | |||
w = w->parentWidget(); | |||
row = rowMap.value(w, -1); | |||
} | |||
if (row != -1) | |||
emit selectRow(row); | |||
} | |||
return ret; | |||
} | |||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const | |||
{ | |||
if( index.row() ==2 &&option.state & QStyle::State_Selected ) { | |||
QStyledItemDelegate::paint(painter, option, index); | |||
painter->fillRect(option.rect, option.palette.highlight()); | |||
painter->drawText(option.rect, Qt::AlignLeft | Qt::AlignVCenter, index.data().toString()); | |||
} else { | |||
return QStyledItemDelegate::paint(painter, option, index); | |||
} | |||
} | |||
signals: | signals: | ||
void selectRow(int); | |||
private: | private: | ||
QMap<QWidget *, int> rowMap; | |||
}; | }; | ||
Line 9,114: | Line 8,935: | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication a(argc, argv); | |||
QTableView tv; | |||
tv.setSelectionBehavior(QTableView::SelectRows); | |||
tv.setModel(new QStandardItemModel(5, 5, &tv)); | |||
MyStyledItemDelegate *msid = new MyStyledItemDelegate(&tv); | |||
tv.setItemDelegate(msid); | |||
tv.openPersistentEditor(tv.model()->index(2,2)); | |||
QObject::connect(msid, SIGNAL(selectRow(int)), &tv, SLOT(selectRow(int))); | |||
tv.show(); | |||
return a.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
===Is it possible to embed one Qt process into another Qt process?=== | ===Is it possible to embed one Qt process into another Qt process?=== | ||
There is no Qt API for embedding a Qt application into another Qt application. If you wish to use widgets from one Qt application in another, then you can use Qt's QAxServer http://doc.qt.io/qt-5 | There is no Qt API for embedding a Qt application into another Qt application. If you wish to use widgets from one Qt application in another, then you can use Qt's QAxServer http://doc.qt.io/qt-5/qaxserver.html module to turn your application executable into an out-of-process ActiveX server that can run the control. | ||
The client application can then use Qt's QAxContainer http://doc.qt.io/qt-5/qaxcontainer.html to embed the control. Note however that widgets can't co-exist in 2 different applications. The QAxServer will create a new instance of the widget whenever it is queried, as widgets can't be shared between applications. | |||
===How to emulate keystroke F1 for use in Qt/MFC Migration Framework solution?=== | ===How to emulate keystroke F1 for use in Qt/MFC Migration Framework solution?=== | ||
The code sample below shows how to emit a F1 key stroke from the QPushButton::clicked() http://doc.qt.io/qt-5 | The code sample below shows how to emit a F1 key stroke from the QPushButton::clicked() http://doc.qt.io/qt-5/qabstractbutton.html#clicked signal (in your Qt application) when wanting your MFC parent application to receive it (not your Qt application). The example uses the Windows API to achieve this: | ||
< | <syntaxhighlight lang="cpp"> | ||
#ifdef WIN32 | #ifdef WIN32 | ||
#include <windows.h> | #include <windows.h> | ||
#endif | #endif | ||
void CMyQtDlg::on_btn_help_clicked() | void CMyQtDlg::on_btn_help_clicked() | ||
{ | { | ||
#ifdef WIN32 | #ifdef WIN32 | ||
if (parentWidget()) | if (parentWidget()) | ||
{ | { | ||
PostMessage(parentWidget()->winId(), WM_KEYDOWN, VK_F1, 0); | PostMessage(parentWidget()->winId(), WM_KEYDOWN, VK_F1, 0); | ||
PostMessage(parentWidget()->winId(), WM_KEYUP, VK_F1, 0); | PostMessage(parentWidget()->winId(), WM_KEYUP, VK_F1, 0); | ||
} | } | ||
#endif | #endif | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Is there a way to create thumbnail for video files?=== | ===Is there a way to create thumbnail for video files?=== | ||
One way to create a thumbnail for video files is to use QPixmap::grabWindow() http://doc.qt.io/qt-5/qpixmap.html#grabWindow to construct a pixmap by grabbing the contents of the given window and then QPixmap::save() http://doc.qt.io/qt-5/qpixmap.html#save to save it. | One way to create a thumbnail for video files is to use QPixmap::grabWindow() http://doc.qt.io/qt-5/qpixmap.html#grabWindow to construct a pixmap by grabbing the contents of the given window and then QPixmap::save() http://doc.qt.io/qt-5/qpixmap.html#save to save it. | ||
The problem with this approach is that if there is any overlapping content it will also grab the overlapping content. | The problem with this approach is that if there is any overlapping content it will also grab the overlapping content. | ||
Another approach, is to use Phonon to load the movie and then use QPixmap::grabWidget() http://doc.qt.io/qt-5/qpixmap.html#grabWidget on the video widget to grab a screenshot of it that you can use as the thumbnail. | |||
===Why do my widgets have a light background in Designer when using QCleanlooksStyle, but a dark background when running the app?=== | ===Why do my widgets have a light background in Designer when using QCleanlooksStyle, but a dark background when running the app?=== | ||
By default we use the system palette for the background. In Designer http://doc.qt.io/qt-5 | By default we use the system palette for the background. In Designer http://doc.qt.io/qt-5/designer-manual.html however, the palette is explicitly set. If you want the same palette as in Designer, you can set it as follows: | ||
< | <syntaxhighlight lang="cpp"> | ||
app.setPalette(app.style()->standardPalette()); | app.setPalette(app.style()->standardPalette()); | ||
</ | </syntaxhighlight> | ||
See the documentation on standardPalette() http://doc.qt.io/qt-5 | See the documentation on standardPalette() http://doc.qt.io/qt-5/qcleanlooksstyle.html#standardPalette | ||
See the following example: | See the following example: | ||
< | <syntaxhighlight lang="cpp"> | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
Line 9,183: | Line 9,004: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Using QGraphicsLineItem with zoom-level-independent selectable regions=== | ===Using QGraphicsLineItem with zoom-level-independent selectable regions=== | ||
If you have a QGraphicsLineItem http://doc.qt.io/qt-5 | If you have a QGraphicsLineItem http://doc.qt.io/qt-5/qgraphicslineitem.html in a QGraphicsScene http://doc.qt.io/qt-5/qgraphicsscene.html with a thin pen, then it can get quite hard to select and/or move it, especially when you zoom out. It is possible to define an invisible region around the line, in which one can select/pick the line, and which is independent of the zoom-level. To do this, one has to reimplement the shape function of the QGraphicLineItem and scale its pen width to the zoomlevel, like this: | ||
< | <syntaxhighlight lang="cpp"> | ||
QPainterPath MyLine::shape() const | QPainterPath MyLine::shape() const | ||
{ | { | ||
Line 9,206: | Line 9,027: | ||
return qt_graphicsItem_shapeFromPath(path, pen1); | return qt_graphicsItem_shapeFromPath(path, pen1); | ||
} | } | ||
</ | </syntaxhighlight> | ||
Note, for this to work, one has to copy the function | Note, for this to work, one has to copy the function | ||
< | <syntaxhighlight lang="cpp">static QPainterPath qt_graphicsItem_shapeFromPath(const QPainterPath &path, const QPen &pen)</syntaxhighlight> | ||
from the file qgraphicsitem.cpp | from the file qgraphicsitem.cpp | ||
In the attached example, you can find this idea implemented. | In the attached example, you can find this idea implemented. | ||
===What can cause the data passed in to QNetworkAccessManager::post() not to be posted when using a sequential QIODevice subclass?=== | ===What can cause the data passed in to QNetworkAccessManager::post() not to be posted when using a sequential QIODevice subclass?=== | ||
This problem can be caused by the readData() http://doc.qt.io/qt-5/qiodevice.html#readData reimplementation never returning -1 and hence not informing that there is no more data to be read. If readData() never returns -1, the data will never be sent because it keeps waiting to be told that there is no more data to be sent. The following report in Jira http://bugreports.qt.io/browse/QTBUG-7648 contains more information on this. | This problem can be caused by the readData() http://doc.qt.io/qt-5/qiodevice.html#readData reimplementation never returning -1 and hence not informing that there is no more data to be read. If readData() never returns -1, the data will never be sent because it keeps waiting to be told that there is no more data to be sent. The following report in Jira http://bugreports.qt.io/browse/QTBUG-7648 contains more information on this. | ||
Line 9,222: | Line 9,043: | ||
===How can I speed up the performance when using QTableWidget::selectRow()?=== | ===How can I speed up the performance when using QTableWidget::selectRow()?=== | ||
It is a known issue that QTableWidget::selectRow() http://doc.qt.io/qt-5 | It is a known issue that QTableWidget::selectRow() http://doc.qt.io/qt-5/qtableview.html#selectRow is slow for large datasets, especially when the items you want to select are spread out over the table. | ||
In order to speed things up, you can use a model with a QTableView http://doc.qt.io/qt-5/qtableview.html instead and subclass QStyledItemDelegate http://doc.qt.io/qt-5 | In order to speed things up, you can use a model with a QTableView http://doc.qt.io/qt-5/qtableview.html instead and subclass QStyledItemDelegate http://doc.qt.io/qt-5/qstyleditemdelegate.html and reimplement its paint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#paint method. In there you can change the option passed in so that the State_Selected http://doc.qt.io/qt-5/qstyle.html#StateFlag-enum is included in the state variable if the index should be painted as selected. Then you can call the base class implementation with the modified option. That way you don't have to do much beyond checking your own storage to see if something should be selected or not. | ||
In order to handle manual mouse selections, you can catch these by handling it yourself in the mousePressEvent() http://doc.qt.io/qt-5/qabstractitemview.html#mousePressEvent, there you can check the modifiers() http://doc.qt.io/qt-5/qinputevent.html#modifiers for the event passed in to see if Ctrl or Shift is being held. | In order to handle manual mouse selections, you can catch these by handling it yourself in the mousePressEvent() http://doc.qt.io/qt-5/qabstractitemview.html#mousePressEvent, there you can check the modifiers() http://doc.qt.io/qt-5/qinputevent.html#modifiers for the event passed in to see if Ctrl or Shift is being held. | ||
To determine which item is actually being clicked on you can use indexAt() http://doc.qt.io/qt-5/qabstractitemview.html#indexAt so that you get the index of the item being selected/deselected. | To determine which item is actually being clicked on you can use indexAt() http://doc.qt.io/qt-5/qabstractitemview.html#indexAt so that you get the index of the item being selected/deselected. | ||
The example below demonstrates how you can implement the itemdelegate part of this. | The example below demonstrates how you can implement the itemdelegate part of this. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class ItemDelegate : public QStyledItemDelegate | class ItemDelegate : public QStyledItemDelegate | ||
{ | { | ||
public: | public: | ||
ItemDelegate(QTableView *view) | |||
{ | |||
myView = view; | |||
QModelIndex start = myView->model()->index(0,0); | |||
mySelectionList = myView->model()->match (start, Qt::DisplayRole, start, -1, Qt::MatchExactly); | |||
} | |||
void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const | |||
{ | |||
if (mySelectionList.contains(index)) { | |||
QStyleOptionViewItem newOption =option; | |||
newOption.state = newOption.state | QStyle::State_Selected; | |||
return QStyledItemDelegate::paint(painter, newOption, index); | |||
} else { | |||
QStyledItemDelegate::paint(painter, option, index); | |||
}} | |||
private: | private: | ||
QTableView *myView; | |||
QModelIndexList mySelectionList; | |||
}; | }; | ||
class TableView : public QTableView | class TableView : public QTableView | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
TableView() | |||
{ | |||
setSelectionMode(QAbstractItemView::MultiSelection); | |||
myModel = new QStringListModel(this); | |||
for (int i = 0; i < 500; i++) { | |||
myList.append(start); | |||
} | |||
for (int i = 500; i < 1000; i++) { | |||
myList.append(middle); | |||
} | |||
for (int i = 1000; i < 2100; i++) { | |||
myList.append(start); | |||
} | |||
myModel->setStringList(myList); | |||
setModel(myModel); | |||
ItemDelegate *myDelegate = new ItemDelegate(this); | |||
setItemDelegate(myDelegate); | |||
} | |||
private: | private: | ||
QStringListModel *myModel; | |||
QStringList myList; | |||
}; | }; | ||
Line 9,296: | Line 9,117: | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
TableView window; | |||
window.show(); | |||
return app.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I detect whether a checkbox was clicked in my QTreeView?=== | ===How can I detect whether a checkbox was clicked in my QTreeView?=== | ||
In order to detect whether the checkbox and not the text of an item was clicked in a QTreeView http://doc.qt.io/qt-5 | In order to detect whether the checkbox and not the text of an item was clicked in a QTreeView http://doc.qt.io/qt-5/qtreeview.html, then you can reimplement the mousePressEvent() http://doc.qt.io/qt-5/qtreeview.html#mousePressEvent and calculate the position of the checkbox there. If the mouse is over the calculated position, then you can for example emit a signal to notify it and do your own handling. Otherwise, simply call the base implementation. | ||
The example below demonstrates how this can be done. | The example below demonstrates how this can be done. | ||
< | <syntaxhighlight lang="cpp">#include <QtWidgets> | ||
class TreeWidget : public QTreeWidget | class TreeWidget : public QTreeWidget | ||
{ | { | ||
public: | public: | ||
TreeWidget() | |||
{ | |||
setColumnCount(1); | |||
item1 = new QTreeWidgetItem(this); | |||
item1->setExpanded(true); | |||
item1->setFlags(item1->flags() | Qt::ItemIsUserCheckable); | |||
item1->setCheckState(0, Qt::Checked); | |||
item1->setText(0, item 1); | |||
item2 = new QTreeWidgetItem(item1); | |||
item2->setFlags(item2->flags() | Qt::ItemIsUserCheckable); | |||
item2->setCheckState(0, Qt::Checked); | |||
item2->setText(0, item 2); | |||
item3 = new QTreeWidgetItem(this); | |||
item3->setText(0, item 3); | |||
item3->setFlags(item3->flags() | Qt::ItemIsUserCheckable); | |||
item3->setCheckState(0, Qt::Checked); | |||
} | |||
void mousePressEvent(QMouseEvent *event) | |||
{ | |||
QModelIndex indexClicked = indexAt(event->pos()); | |||
if(indexClicked.isValid()) { | |||
QRect vrect = visualRect(indexClicked); | |||
int itemIndentation = vrect.x() - visualRect(rootIndex()).x(); | |||
QRect rect = QRect(header()->sectionViewportPosition(0) + itemIndentation | |||
, vrect.y(), style()->pixelMetric(QStyle::PM_IndicatorWidth), vrect.height()); | |||
if(rect.contains(event->pos())) { | |||
qDebug() << checkbox clicked; | |||
QTreeWidget::mousePressEvent(event); | |||
return; | |||
} else { | |||
QTreeWidget::mousePressEvent(event); | |||
}}} | |||
private: | private: | ||
QTreeWidgetItem *item1; | |||
QTreeWidgetItem *item2; | |||
QTreeWidgetItem *item3; | |||
QTreeWidgetItem *item4; | |||
}; | }; | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
TreeWidget box; | |||
box.show(); | |||
return app.exec(); | |||
}</ | }</syntaxhighlight> | ||
===How can I replace the checkbox indicator of a QListWidgetItem with an icon?=== | ===How can I replace the checkbox indicator of a QListWidgetItem with an icon?=== | ||
In order to style the checkbox indicator of a QListWidgetItem http://doc.qt.io/qt-5 | In order to style the checkbox indicator of a QListWidgetItem http://doc.qt.io/qt-5/qlistwidgetitem.html, you can set a stylesheet on the QListWidget http://doc.qt.io/qt-5/qlistwidget.html that passes in the image you want when the subcontrol is :item http://doc.qt.io/qt-5/stylesheet-reference.html#list-of-sub-controls and the pseudo states http://doc.qt.io/qt-5/stylesheet-reference.html#list-of-pseudo-states are :checked, :unchecked and :indeterminate, see the documentation: | ||
The example below demonstrates how this can be done. | The example below demonstrates how this can be done. | ||
< | <syntaxhighlight lang="cpp">#include <QtWidgets> | ||
class ListWidget : public QListWidget | class ListWidget : public QListWidget | ||
{ | { | ||
public: | public: | ||
ListWidget() | |||
{ | |||
QListWidgetItem *firstItem = new QListWidgetItem(First, this); | |||
firstItem->setFlags(firstItem->flags() |Qt::ItemIsUserCheckable); | |||
firstItem->setCheckState(Qt::Checked); | |||
QListWidgetItem *secondItem = new QListWidgetItem(Second, this); | |||
addItem(firstItem); | |||
addItem(secondItem); | |||
setStyleSheet(QListWidget::indicator:checked { image: url(checked.png);} \ | |||
QListWidget::indicator:unchecked { image: url(unchecked.png)}\ | |||
QListWidget::indicator:indeterminate { image: url(indeterminate.png);}" | |||
); | |||
}}; | |||
int main(int argc, char** argv) | |||
{ | |||
QApplication app(argc, argv); | |||
ListWidget window; | |||
window.show(); | |||
return app.exec(); | |||
}</syntaxhighlight> | |||
===How can I make long text appear elided for a QAction?=== | ===How can I make long text appear elided for a QAction?=== | ||
Line 9,408: | Line 9,229: | ||
The example below demonstrates how this can be done. | The example below demonstrates how this can be done. | ||
< | <syntaxhighlight lang="cpp">#include <QtWidgets> | ||
class MainWindow : public QMainWindow | class MainWindow : public QMainWindow | ||
{ | { | ||
public: | public: | ||
MainWindow() | |||
{ | |||
QMenu *menu = menuBar()->addMenu(Test); | |||
QAction *firstAction = new QAction(this); | |||
QString firstText = fontMetrics().elidedText(Normal Text, Qt::ElideMiddle, 100); | |||
firstAction->setText(firstText); | |||
menu->addAction(firstAction); | |||
QAction *secondAction = new QAction(this); | |||
QString secondText = fontMetrics().elidedText(Some wiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiide text, Qt::ElideMiddle,100); | |||
secondAction->setText(secondText); | |||
menu->addAction(secondAction); | |||
setCentralWidget(new QTextEdit(this)); | |||
} | |||
}; | }; | ||
int main(int argc, char** argv) | |||
{ | |||
QApplication app(argc, argv); | |||
MainWindow window; | |||
window.show(); | |||
return app.exec(); | |||
}</syntaxhighlight> | |||
===How can I remove the dotted rectangle from the cell that has focus in my QTableView?=== | ===How can I remove the dotted rectangle from the cell that has focus in my QTableView?=== | ||
In order to remove the dotted rectangle that appears when a cell is clicked, then you can subclass the QStyledItemDelegate http://doc.qt.io/qt-5 | In order to remove the dotted rectangle that appears when a cell is clicked, then you can subclass the QStyledItemDelegate http://doc.qt.io/qt-5/qstyleditemdelegate.html class and reimplement the paint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#paint function to remove the State_HasFocus http://doc.qt.io/qt-5/qstyle.html#StateFlag-enum state from the option's state, so that the dotted focus rectangle does not appear. | ||
The example below demonstrates how this can be done. | The example below demonstrates how this can be done. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class StyledItemDelegate : public QStyledItemDelegate | class StyledItemDelegate : public QStyledItemDelegate | ||
{ | { | ||
public: | public: | ||
StyledItemDelegate(QObject *parent = NULL) : | |||
QStyledItemDelegate(parent) {} | |||
void paint(QPainter *painter, const QStyleOptionViewItem &option, | |||
const QModelIndex &index) const | |||
{ | |||
QStyleOptionViewItem opt = option; | |||
opt.state &= ~QStyle::State_HasFocus; | |||
QStyledItemDelegate::paint(painter, opt, index); | |||
} | |||
}; | }; | ||
Line 9,465: | Line 9,286: | ||
class TableWidget : public QTableWidget | class TableWidget : public QTableWidget | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
TableWidget(QWidget *parent = nullptr) | |||
: QTableWidget(ROWS, COLS, parent) | |||
{ | |||
setItemDelegate(new StyledItemDelegate(this)); | |||
setSelectionMode(QAbstractItemView::SingleSelection); | |||
setSelectionBehavior(QAbstractItemView::SelectRows); | |||
for (int i=0; i<rowCount(); ++i) { | |||
for (int j=0; j<columnCount(); ++j) { | |||
setItem(i, j, new QTableWidgetItem(QString(%1).arg(i * | |||
rowCount() + j))); | |||
} | |||
} | |||
} | |||
}; | }; | ||
Line 9,486: | Line 9,307: | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication a(argc, argv); | |||
TableWidget w; | |||
w.show(); | |||
return a.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
===Is it possible to translate the native filedialogs used on Windows and Mac ?=== | ===Is it possible to translate the native filedialogs used on Windows and Mac ?=== | ||
This is not possible, since they are provided by Windows. The filedialogs will get the text of the language of the Windows/Mac version. So if you are on a German version of Windows, the buttons etc. in the native filedialog will appear in German. There is nothing we can do to change that in Qt. | This is not possible, since they are provided by Windows. The filedialogs will get the text of the language of the Windows/Mac version. So if you are on a German version of Windows, the buttons etc. in the native filedialog will appear in German. There is nothing we can do to change that in Qt. | ||
===How can I set up my environment for building Qt/Qt applications with MinGW?=== | ===How can I set up my environment for building Qt/Qt applications with MinGW?=== | ||
Line 9,507: | Line 9,328: | ||
2) Download the qt-everywhere-someVersion.zip package | 2) Download the qt-everywhere-someVersion.zip package | ||
3) Open a command prompt by typing | 3) Open a command prompt by typing | ||
< | <syntaxhighlight lang="cpp"> cmd</syntaxhighlight> | ||
in Run/Search in the Start Menu | in Run/Search in the Start Menu | ||
Line 9,522: | Line 9,343: | ||
and then type | and then type | ||
< | <syntaxhighlight lang="cpp">configure -anyOptionsYouWant && mingw32-make</syntaxhighlight> | ||
in this command prompt | in this command prompt | ||
5) When building Qt applications, add yourQtVersion\bin to the PATH environment variable like: | 5) When building Qt applications, add yourQtVersion\bin to the PATH environment variable like: | ||
< | <syntaxhighlight lang="cpp"> set PATH=yourQtVersion\bin;%PATH%</syntaxhighlight> | ||
===QWidget ::activateWindow() - behavior under windows=== | ===QWidget ::activateWindow() - behavior under windows=== | ||
The documentation for QWidget::activateWindow() http://doc.qt.io/qt-5 | The documentation for QWidget::activateWindow() http://doc.qt.io/qt-5/qwidget.html#activateWindow states: | ||
On Windows, if you are calling this when the application is not currently the active one then it will not make it the active window. It will change the color of the taskbar entry to indicate that the window has changed in some way. This is because Microsoft does not allow an application to interrupt what the user is currently doing in another application." | On Windows, if you are calling this when the application is not currently the active one then it will not make it the active window. It will change the color of the taskbar entry to indicate that the window has changed in some way. This is because Microsoft does not allow an application to interrupt what the user is currently doing in another application." | ||
Line 9,538: | Line 9,359: | ||
However, there is a workaround for this problem. Namely changing the following registry keys will result in the desired behaviour | However, there is a workaround for this problem. Namely changing the following registry keys will result in the desired behaviour | ||
< | <syntaxhighlight lang="cpp">HKEY_CURRENT_USER\Control Panel\Desktop | ||
ForegroundFlashCount = REG_DWORD 0x00000003 | ForegroundFlashCount = REG_DWORD 0x00000003 | ||
ForegroundLockTimeout = REG_DWORD 0x00000000</ | ForegroundLockTimeout = REG_DWORD 0x00000000</syntaxhighlight> | ||
These registry entries can be set using QSettings http://doc.qt.io/qt-5/qsettings.html . | These registry entries can be set using QSettings http://doc.qt.io/qt-5/qsettings.html . | ||
Line 9,546: | Line 9,367: | ||
e.g: | e.g: | ||
< | <syntaxhighlight lang="cpp"> | ||
QSettings settings("HKEY_CURRENT_USER\\Control Panel\\Desktop ", QSettings::NativeFormat, this); | QSettings settings("HKEY_CURRENT_USER\\Control Panel\\Desktop ", QSettings::NativeFormat, this); | ||
settings.setValue("ForegroundFlashCount", 3); | settings.setValue("ForegroundFlashCount", 3); | ||
settings.setValue("ForegroundLockTimeout", 0 ); | settings.setValue("ForegroundLockTimeout", 0 ); | ||
</ | </syntaxhighlight> | ||
Note that changing these registry settings using QSettings will change them globally on your computer, not only for your application. | Note that changing these registry settings using QSettings will change them globally on your computer, not only for your application. | ||
Line 9,558: | Line 9,379: | ||
It has been suggested to add this workaround to the Qt Documentation, see: | It has been suggested to add this workaround to the Qt Documentation, see: | ||
http://bugreports.qt.io/browse/QTBUG-14062 | http://bugreports.qt.io/browse/QTBUG-14062 | ||
===How can I show close(x) button for each tab in a QMdiArea?=== | ===How can I show close(x) button for each tab in a QMdiArea?=== | ||
In order to show close buttons on the tabbed windows in a QMdiArea http://doc.qt.io/qt-5 | In order to show close buttons on the tabbed windows in a QMdiArea http://doc.qt.io/qt-5/qmdiarea.html, you need to get hold of the underlying QTabBar http://doc.qt.io/qt-5/qtabbar.html and call setTabsClosable() http://doc.qt.io/qt-5/qtabbar.html#tabsClosable-prop with true as an argument on it. Then you can connect its tabCloseRequested() http://doc.qt.io/qt-5/qtabbar.html#tabCloseRequested signal to a slot that closes the relevant tab. | ||
The example below illustrates how this can be done. | The example below illustrates how this can be done. | ||
< | <syntaxhighlight lang="cpp">#include <QtWidgets> | ||
class MdiArea : public QMdiArea | class MdiArea : public QMdiArea | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
MdiArea(QWidget *parent) : QMdiArea(parent) | |||
{ | |||
setViewMode(QMdiArea::TabbedView); | |||
QMdiSubWindow *subWindow1 = new QMdiSubWindow; | |||
subWindow1->setWidget(new QTextEdit(this)); | |||
subWindow1->setAttribute(Qt::WA_DeleteOnClose); | |||
addSubWindow(subWindow1); | |||
QMdiSubWindow *subWindow2 = addSubWindow(new QPushButton(some text), 0); | |||
QList<QTabBar*> tabBarList = findChildren <QTabBar*>(); | |||
tabBar = tabBarList.at(0); | |||
if (tabBar) { | |||
tabBar->setTabsClosable(true); | |||
connect(tabBar, SIGNAL(tabCloseRequested(int)), this, SLOT(testSlot(int))); | |||
}} | |||
public slots: | |||
void testSlot(int closeThisTab) | |||
{ | |||
tabBar->removeTab(closeThisTab); | |||
} | |||
private: | private: | ||
QTabBar *tabBar; | |||
}; | }; | ||
class MainWindow : public QMainWindow | class MainWindow : public QMainWindow | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
MainWindow() | |||
{ | |||
area = new MdiArea(this); | |||
setCentralWidget(area); | |||
QToolBar *toolBar = new QToolBar(this); | |||
QAction *closeAction = new QAction(this); | |||
closeAction->setText(Close all); | |||
toolBar->addAction(closeAction); | |||
addToolBar(toolBar); | |||
connect(closeAction, SIGNAL(triggered(bool)), this, SLOT(testSlot(bool))); | |||
} | |||
public slots: | |||
void testSlot(bool closeThem) | |||
{ | |||
area->closeAllSubWindows(); | |||
} | |||
private: | private: | ||
MdiArea *area; | |||
}; | }; | ||
#include main.moc" | #include main.moc" | ||
int main(int argc, char** argv) | |||
{ | |||
QApplication app(argc, argv); | |||
MainWindow window; | |||
window.show(); | |||
return app.exec(); | |||
} | |||
</syntaxhighlight> | |||
===How can I drag items between a QToolBar and a QListWidget?=== | ===How can I drag items between a QToolBar and a QListWidget?=== | ||
In order to allow toolbuttons to be dragged from a QToolBar http://doc.qt.io/qt-5 | In order to allow toolbuttons to be dragged from a QToolBar http://doc.qt.io/qt-5/qtoolbar.html and dropped as items in a QListWidget http://doc.qt.io/qt-5/qlistwidget.html, then you need to make the widgets aware of drag and drop operations. This can be done by subclassing QToolButton http://doc.qt.io/qt-5/qtoolbutton.html and implementing a function for it that stores the data that is to be transferred in a QMimeData http://doc.qt.io/qt-5/qmimedata.html object. | ||
Then in order for the QListWidget to receive the data, you need to reimplement its dragEnterEvent() http://doc.qt.io/qt-5/qabstractitemview.html#dragEnterEvent, dragMoveEvent() http://doc.qt.io/qt-5/qlistview.html#dragMoveEvent and dropEvent () http://doc.qt.io/qt-5/qlistwidget.html#dropEvent functions, in addition to calling setAcceptDrops() http://doc.qt.io/qt-5/qwidget.html#acceptDrops-prop with true as an argument. | Then in order for the QListWidget to receive the data, you need to reimplement its dragEnterEvent() http://doc.qt.io/qt-5/qabstractitemview.html#dragEnterEvent, dragMoveEvent() http://doc.qt.io/qt-5/qlistview.html#dragMoveEvent and dropEvent () http://doc.qt.io/qt-5/qlistwidget.html#dropEvent functions, in addition to calling setAcceptDrops() http://doc.qt.io/qt-5/qwidget.html#acceptDrops-prop with true as an argument. | ||
Similarly, in order to drag items from the QListWidget to the QToolBar, you can reimplement QListWidget::startDrag() http://doc.qt.io/qt-5 | Similarly, in order to drag items from the QListWidget to the QToolBar, you can reimplement QListWidget::startDrag() http://doc.qt.io/qt-5/qlistview.html#startDrag and store the data in a QMimeData object that the toolbar will receive. | ||
The example below illustrates how this can be done. | The example below illustrates how this can be done. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class ToolButton : public QToolButton | class ToolButton : public QToolButton | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
ToolButton(QWidget *parent) : QToolButton(parent) | |||
{ | |||
connect(this, SIGNAL(pressed()), this, SLOT(startDrag())); | |||
} | |||
public slots: | |||
void startDrag() | |||
{ | |||
QDrag *dr = new QDrag(this); | |||
// The data to be transferred by the drag and drop operation is contained in a QMimeData object | |||
QMimeData *mimeData = new QMimeData; | |||
QByteArray ba = text().toLatin1().data(); | |||
QString theText = bla/x-something; | |||
mimeData->setData(theText, ba); | |||
// Assign ownership of the QMimeData object to the QDrag object. | |||
dr->setMimeData(mimeData); | |||
// Start the drag and drop operation | |||
if (dr->start(Qt::MoveAction)) | |||
deleteLater(); | |||
} | |||
}; | }; | ||
class ToolBar : public QToolBar | class ToolBar : public QToolBar | ||
{ | { | ||
public: | |||
ToolBar(QMainWindow *window) : QToolBar(window) | |||
{ | |||
setAcceptDrops(true); | |||
} | |||
void dragEnterEvent(QDragEnterEvent *event) | |||
{ | |||
if (event->mimeData()->hasFormat(bla/x-something)) | |||
event->acceptProposedAction(); | |||
} | |||
void dropEvent(QDropEvent *event) | |||
{ | |||
if (event->mimeData()->hasFormat(bla/x-something)) { | |||
event->accept(); | |||
event->setDropAction(Qt::MoveAction); | |||
QByteArray pieceData = event->mimeData()->data(bla/x-something); | |||
QDataStream dataStream(&pieceData, QIODevice::ReadOnly); | |||
ToolButton *button = new ToolButton(this); | |||
button->setText(pieceData); | |||
addWidget(button); | |||
} else { | |||
event->ignore(); | |||
} | } | ||
} | } | ||
Line 9,706: | Line 9,527: | ||
class ListWidget : public QListWidget | class ListWidget : public QListWidget | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
ListWidget(QWidget *parent) : QListWidget(parent) | |||
{ | |||
addItem(First); | |||
addItem(Second); | |||
addItem(Third); | |||
setDragEnabled(true); | |||
setAcceptDrops(true); | |||
} | |||
void dragEnterEvent(QDragEnterEvent *event) | |||
{ | |||
if (event->mimeData()->hasFormat(bla/x-something)) | |||
event->accept(); | |||
else | |||
event->ignore(); | |||
} | |||
void dragMoveEvent(QDragMoveEvent *event) | |||
{ | |||
if (event->mimeData()->hasFormat(bla/x-something)) { | |||
event->setDropAction(Qt::MoveAction); | |||
event->accept(); | |||
} else | |||
event->ignore(); | |||
} | |||
Qt::DropActions supportedDropActions () const | |||
{ | |||
return Qt::MoveAction; | |||
} | |||
void dropEvent(QDropEvent *event) | |||
{ | |||
if (event->mimeData()->hasFormat(bla/x-something)) { | |||
event->accept(); | |||
event->setDropAction(Qt::MoveAction); | |||
QByteArray pieceData = event->mimeData()->data(bla/x-something); | |||
addItem(pieceData); | |||
} else | |||
event->ignore(); | |||
} | |||
void startDrag(Qt::DropActions) | |||
{ | |||
QListWidgetItem *item = currentItem(); | |||
QMimeData *mimeData = new QMimeData; | |||
QByteArray ba = item->text().toLatin1().data(); | |||
QString theText = bla/x-something; | |||
mimeData->setData(theText, ba); | |||
QDrag *drag = new QDrag(this); | |||
drag->setMimeData(mimeData); | |||
if (drag->exec(Qt::MoveAction) == Qt::MoveAction) | |||
delete takeItem(row(item)); | |||
} | |||
}; | }; | ||
Line 9,764: | Line 9,585: | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
QMainWindow window; | |||
window.setCentralWidget(new ListWidget(&window)); | |||
ToolBar *toolBar = new ToolBar(&window); | |||
ToolButton *button1 = new ToolButton(toolBar); | |||
button1->setText(Button 1); | |||
ToolButton *button2 = new ToolButton(toolBar); | |||
button2->setText(Button 2); | |||
toolBar->addWidget(button1); | |||
toolBar->addWidget(button2); | |||
window.addToolBar(toolBar); | |||
window.show(); | |||
return app.exec(); | |||
}</ | }</syntaxhighlight> | ||
===When setting a background pixmap for a widget, it is tiled if the pixmap is smaller than the widget. Is there a way to avoid this?=== | ===When setting a background pixmap for a widget, it is tiled if the pixmap is smaller than the widget. Is there a way to avoid this?=== | ||
In order to avoid the image from being tiled, you can catch the resizeEvent() http://doc.qt.io/qt-5 | In order to avoid the image from being tiled, you can catch the resizeEvent() http://doc.qt.io/qt-5/qwidget.html#resizeEvent and scale it to fit the size of the widget. The example below illustrates how this can be done. It creates a new image the same size as the widget, fills it with gray, and then draws the background image centered on it, with the aspect ratio preserved. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class MdiArea : public QMdiArea | class MdiArea : public QMdiArea | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
MdiArea() | |||
{ | |||
i = QImage(logo.png); | |||
} | |||
protected: | protected: | ||
void resizeEvent(QResizeEvent *resizeEvent) | |||
{ | |||
QImage newBackground(resizeEvent->size(), QImage::Format_ARGB32_Premultiplied); | |||
QPainter p(&newBackground); | |||
p.fillRect(newBackground.rect(), Qt::gray); | |||
QImage scaled = i.scaled(resizeEvent->size(),Qt::KeepAspectRatio); | |||
QRect scaledRect = scaled.rect(); | |||
scaledRect.moveCenter(newBackground.rect().center()); | |||
p.drawImage(scaledRect, scaled); | |||
setBackground(newBackground); | |||
QMdiArea::resizeEvent(resizeEvent); | |||
} | |||
private: | private: | ||
QImage i; | |||
}; | }; | ||
Line 9,817: | Line 9,638: | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
MdiArea box; | |||
box.resize(400, 400); | |||
box.show(); | |||
return app.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
===The performance is slow and some data is lost when sending data using QTcpSocket at short intervals, what can be wrong?=== | ===The performance is slow and some data is lost when sending data using QTcpSocket at short intervals, what can be wrong?=== | ||
The performance of QTcpSocket http://doc.qt.io/qt-5 | The performance of QTcpSocket http://doc.qt.io/qt-5/qtcpsocket.html can decrease and data can get lost if the socket is not set up correctly in the application. If the socket and server are handled in the same class and the QTcpSocket object is being reused, then this can cause the problem. The recommended pattern is: | ||
# Don't do client and server in same class. | # Don't do client and server in same class. | ||
# If you for some reason have to do it in the same class, then don't handle multiple sockets with one object. Make sure the QTcpSocket object is created locally in each function and ensure that it is deleted when it is disconnected, e.g: | # If you for some reason have to do it in the same class, then don't handle multiple sockets with one object. Make sure the QTcpSocket object is created locally in each function and ensure that it is deleted when it is disconnected, e.g: | ||
< | <syntaxhighlight lang="cpp"> | ||
void processReadyRead() | void processReadyRead() | ||
{ | { | ||
Line 9,839: | Line 9,660: | ||
} | } | ||
</ | </syntaxhighlight> | ||
The example below demonstrates how this can be set up. | The example below demonstrates how this can be set up. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
#include <QtNetwork> | #include <QtNetwork> | ||
class MainWindow : public QMainWindow | class MainWindow : public QMainWindow | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
MainWindow() | |||
{ | |||
textEdit = new QTextEdit(this); | |||
setCentralWidget(textEdit); | |||
QTimer *timer = new QTimer(this); | |||
timer->start(1); | |||
myServer = new QTcpServer (this); | |||
if (!myServer->listen(QHostAddress(127.0.0.1), 61031)) | |||
{ | |||
exit(-1); //error | |||
} | |||
connect(timer, SIGNAL(timeout()), this, SLOT(testSlot())); | |||
connect(myServer, SIGNAL(newConnection()), this, SLOT(processNewConnection())); | |||
} | |||
public slots: | |||
void processNewConnection() | |||
{ | |||
//Create the socket locally using nextPendingConnection | |||
QTcpSocket *testSocket = myServer->nextPendingConnection(); | |||
if (testSocket) | |||
{ | |||
//Avoid memory leakage by deleting the socket when it is disconnected | |||
connect(testSocket, SIGNAL(disconnected()), testSocket, SLOT(deleteLater())); | |||
connect(testSocket, SIGNAL(readyRead()), this, SLOT(processReadyRead())); | |||
connect(testSocket, SIGNAL(disconnected()), testSocket, SLOT(deleteLater())); | |||
} | |||
} | |||
void processReadyRead() | |||
{ | |||
//Use QOject::sender to get the socket that sent the data | |||
QTcpSocket* mySocket = qobject_cast <QTcpSocket*>(sender()); | |||
QByteArray block = mySocket->readAll(); | |||
QDataStream in(&block, QIODevice::ReadOnly); | |||
in.setVersion(QDataStream::Qt_4_0); | |||
QString receiveString; | |||
in >> receiveString; | |||
textEdit->setText(receiveString); | |||
connect(mySocket, SIGNAL(disconnected()), mySocket, SLOT(deleteLater())); | |||
} | |||
void testSlot() | |||
{ | |||
QTcpSocket *aClientConnection = new QTcpSocket(); | |||
connect(aClientConnection, SIGNAL(disconnected()), aClientConnection, SLOT(deleteLater())); | |||
aClientConnection->connectToHost(QHostAddress(127.0.0.1), 61031); | |||
QByteArray block; | |||
QDataStream out(&block, QIODevice::WriteOnly); | |||
out.setVersion(QDataStream::Qt_4_0); | |||
QString sendString; | |||
for (int i=0;i<1000;i++) | |||
sendString = Make sure the socket is created and destroyed locally in each function, don't reuse one object for them.; | |||
out << sendString; | |||
aClientConnection->write(block); | |||
} | |||
private: | private: | ||
QTcpServer *myServer; | |||
QTextEdit *textEdit; | |||
}; | }; | ||
Line 9,920: | Line 9,741: | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
MainWindow window; | |||
window.show(); | |||
return app.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I create a one-line QTextEdit?=== | ===How can I create a one-line QTextEdit?=== | ||
You can create a single line QTextEdit http://doc.qt.io/qt-5 | You can create a single line QTextEdit http://doc.qt.io/qt-5/qtextedit.html by subclassing QTextEdit and doing the following: | ||
1. Disable word wrap. | 1. Disable word wrap. | ||
Line 9,938: | Line 9,759: | ||
4. Set the sizePolicy to (QSizePolicy::Expanding, QSizePolicy::Fixed) | 4. Set the sizePolicy to (QSizePolicy::Expanding, QSizePolicy::Fixed) | ||
4. Reimplement keyPressEvent() to ignore the event when Enter/Return is hit | 4. Reimplement keyPressEvent() to ignore the event when Enter/Return is hit | ||
5. Reimplement sizeHint to return size depending on the font. It can be based on QLineEdit's sizeHint() http://doc.qt.io/qt-5 | 5. Reimplement sizeHint to return size depending on the font. It can be based on QLineEdit's sizeHint() http://doc.qt.io/qt-5/qlineedit.html#sizeHint. | ||
The example below demonstrates how this can be done. | The example below demonstrates how this can be done. | ||
< | <syntaxhighlight lang="cpp">#include <QtWidgets> | ||
class TextEdit : public QTextEdit | class TextEdit : public QTextEdit | ||
{ | { | ||
public: | public: | ||
TextEdit() | |||
{ | |||
setTabChangesFocus(true); | |||
setWordWrapMode(QTextOption::NoWrap); | |||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); | |||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); | |||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); | |||
setFixedHeight(sizeHint().height()); | |||
} | |||
void keyPressEvent(QKeyEvent *event) | |||
{ | |||
if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) | |||
event->ignore(); | |||
else | |||
QTextEdit::keyPressEvent(event); | |||
} | |||
QSize sizeHint() const | |||
{ | |||
QFontMetrics fm(font()); | |||
int h = qMax(fm.height(), 14) + 4; | |||
int w = fm.width(QLatin1Char('x')) * 17 + 4; | |||
QStyleOptionFrameV2 opt; | |||
opt.initFrom(this); | |||
return (style()->sizeFromContents(QStyle::CT_LineEdit, &opt, QSize(w, h). | |||
expandedTo(QApplication::globalStrut()), this)); | |||
} | |||
}; | }; | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
TextEdit window; | |||
window.show(); | |||
return app.exec(); | |||
}</syntaxhighlight> | |||
===How can I make Assistant look for translations outside qtVersion/translations when deploying my application?=== | ===How can I make Assistant look for translations outside qtVersion/translations when deploying my application?=== | ||
You can provide a qt.conf http://doc.qt.io/qt-5/qt-conf.html file with your application which indicates where the translations are located. | You can provide a qt.conf http://doc.qt.io/qt-5/qt-conf.html file with your application which indicates where the translations are located. | ||
The content of your qt.conf file can look something like the following for example: | The content of your qt.conf file can look something like the following for example: | ||
< | <syntaxhighlight lang="cpp">[Paths] | ||
Translations =c:\\xxx\\translations</ | Translations =c:\\xxx\\translations</syntaxhighlight> | ||
===How can I make the QSsl... classes work on Windows?=== | ===How can I make the QSsl... classes work on Windows?=== | ||
Line 9,999: | Line 9,820: | ||
1) Install OpenSSL from the following link: | 1) Install OpenSSL from the following link: | ||
http://www.openssl.org/ | http://www.openssl.org/ | ||
Alternatively, from the link below which contains an installer that will ensure that OpenSSL installs correctly. | Alternatively, from the link below which contains an installer that will ensure that OpenSSL installs correctly. | ||
Line 10,007: | Line 9,828: | ||
2) Add global environment variables similar to the following: | 2) Add global environment variables similar to the following: | ||
< | <syntaxhighlight lang="cpp">INCLUDE=C:\OpenSSL-Win32\include; | ||
LIB=C:\OpenSSL-Win32\lib; | LIB=C:\OpenSSL-Win32\lib; | ||
PATH= C:\OpenSSL-Win32\bin</ | PATH= C:\OpenSSL-Win32\bin</syntaxhighlight> | ||
3) Configure Qt with the | 3) Configure Qt with the | ||
< | <syntaxhighlight lang="cpp">configure -openssl</syntaxhighlight> | ||
option | option | ||
Line 10,021: | Line 9,842: | ||
http://doc.qt.io/qt-5/ssl.html | http://doc.qt.io/qt-5/ssl.html | ||
http://doc.qt.io/qt-5/requirements.html | http://doc.qt.io/qt-5/requirements.html | ||
==="Why do I get the following error when using QPainter: QPainter::begin: Paint device returned engine == 0, type: 1?"=== | ==="Why do I get the following error when using QPainter: QPainter::begin: Paint device returned engine == 0, type: 1?"=== | ||
This error can occur if you try to use the painter on a subclass of QScrollArea http://doc.qt.io/qt-5 | This error can occur if you try to use the painter on a subclass of QScrollArea http://doc.qt.io/qt-5/qscrollarea.html, and you don't pass in the viewport() http://doc.qt.io/qt-5/qabstractscrollarea.html#viewport as the device to paint on. So if you are painting on a QTableWidget http://doc.qt.io/qt-5/qtablewidget.html for instance, make sure you instantiate the painter as follows: | ||
< | <syntaxhighlight lang="cpp"> | ||
QPainter painter(tableWidget->viewport()); | QPainter painter(tableWidget->viewport()); | ||
</ | </syntaxhighlight> | ||
===How can I display a flash file in a QWebView and ensure that nobody can copy the file?=== | ===How can I display a flash file in a QWebView and ensure that nobody can copy the file?=== | ||
In order to display flash videos, you need to set the PluginsEnabled http://doc.qt.io/qt-5 | In order to display flash videos, you need to set the PluginsEnabled http://doc.qt.io/qt-5/qwebsettings.html#WebAttribute-enum attribute on the object returned by QWebSettings.globalSettings() http://doc.qt.io/qt-5/qwebsettings.html#globalSettings. See the documentation http://doc.qt.io/qt-5/qtwebkit.html#netscape-plugin-support for more details about using plugins. | ||
To make it impossible for others to copy the flash file, you can add it as a resource http://doc.qt.io/qt-5/resources.html, this way the file will be stored in the application executable. | To make it impossible for others to copy the flash file, you can add it as a resource http://doc.qt.io/qt-5/resources.html, this way the file will be stored in the application executable. | ||
Finally, you need to call | Finally, you need to call | ||
< | <syntaxhighlight lang="cpp">QWebSecurityOrigin::addLocalScheme(qrc) </syntaxhighlight> | ||
to ensure the webview will understand the content from resource files, see the documentation on addLocalScheme() http://doc.qt.io/qt-5/qwebsecurityorigin.html#addLocalScheme | to ensure the webview will understand the content from resource files, see the documentation on addLocalScheme() http://doc.qt.io/qt-5/qwebsecurityorigin.html#addLocalScheme | ||
Line 10,044: | Line 9,865: | ||
The example below illustrates this approach. | The example below illustrates this approach. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
#include <QtWebKit> | #include <QtWebKit> | ||
Line 10,051: | Line 9,872: | ||
{ | { | ||
public: | public: | ||
WebView() | |||
{ | |||
settings()->globalSettings()->setAttribute(QWebSettings::PluginsEnabled, true); | |||
QWebSecurityOrigin::addLocalScheme(qrc); | |||
load(QUrl::fromLocalFile(AbsolutePathTo/A-Sample-SWF-File.htm)); | |||
} | |||
}; | }; | ||
Line 10,063: | Line 9,884: | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
WebView window; | |||
window.show(); | |||
return app.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
===Why does not unicode characters show up for indices in my help documentation?=== | ===Why does not unicode characters show up for indices in my help documentation?=== | ||
Line 10,079: | Line 9,900: | ||
3) Save the file as unicode | 3) Save the file as unicode | ||
4) Clear the assistant cache under QDesktopServices::dataLocation/Trolltech | 4) Clear the assistant cache under QDesktopServices::dataLocation/Trolltech | ||
===When using the Alt key as a shortcut in my application, then why don't I get a release event when hitting Alt+Tab?=== | ===When using the Alt key as a shortcut in my application, then why don't I get a release event when hitting Alt+Tab?=== | ||
Alt+Tab is a key combination controlled by Windows, so Windows will grab the event which is why you don't get a release event. If you need a key release event to be issued however, then you can listen for the QEvent::ActivationChange http://doc.qt.io/qt-5/qevent.html#Type-enum and if the Alt key is pressed when you get a QEvent::ActivationChange, then you can send the key release event yourself using QCoreApplication::sendEvent() http://doc.qt.io/qt-5 | Alt+Tab is a key combination controlled by Windows, so Windows will grab the event which is why you don't get a release event. If you need a key release event to be issued however, then you can listen for the QEvent::ActivationChange http://doc.qt.io/qt-5/qevent.html#Type-enum and if the Alt key is pressed when you get a QEvent::ActivationChange, then you can send the key release event yourself using QCoreApplication::sendEvent() http://doc.qt.io/qt-5/qcoreapplication.html#sendEvent | ||
The example below illustrates how this can be done. | The example below illustrates how this can be done. | ||
< | <syntaxhighlight lang="cpp">#include <QtWidgets> | ||
class MainWindow : public QMainWindow | class MainWindow : public QMainWindow | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
MainWindow() | |||
{ | |||
altIsPressed = false; | |||
setFocusPolicy(Qt::StrongFocus); | |||
} | |||
bool event(QEvent *myEvent) | |||
{ | |||
if (myEvent->type() == QEvent::ActivationChange && altIsPressed) { | |||
qDebug() << Activation Change; | |||
QKeyEvent *keyEvent = new QKeyEvent(QEvent::KeyRelease, Qt::Key_Alt, Qt::NoModifier); | |||
QApplication::sendEvent(this, keyEvent); | |||
} | |||
return QMainWindow::event(myEvent); | |||
} | |||
void keyPressEvent(QKeyEvent *event) | |||
{ | |||
if (event->modifiers() == Qt::AltModifier) | |||
{ | |||
qDebug() << KEY PRESS; | |||
altIsPressed = true; | |||
return QMainWindow::keyPressEvent(event); | |||
} | |||
return QMainWindow::keyPressEvent(event); | |||
} | |||
void keyReleaseEvent(QKeyEvent *event) | |||
{ | |||
qDebug() << KEY RELEASE; | |||
altIsPressed = false; | |||
return QMainWindow::keyReleaseEvent(event); | |||
} | |||
bool altIsPressed; | |||
}; | }; | ||
Line 10,132: | Line 9,953: | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
MainWindow window; | |||
window.show(); | |||
return app.exec(); | |||
}</syntaxhighlight> | |||
===After installing the binary Qt package for VS 2005, Qt Designer won't run, what is causing this problem?=== | ===After installing the binary Qt package for VS 2005, Qt Designer won't run, what is causing this problem?=== | ||
Line 10,149: | Line 9,970: | ||
# Open the command prompt provided with Visual Studio 2005 | # Open the command prompt provided with Visual Studio 2005 | ||
# Go to the Qt directory and type | # Go to the Qt directory and type | ||
< | <syntaxhighlight lang="cpp">configure | ||
nmake</ | nmake</syntaxhighlight> | ||
# In this command prompt, type: | # In this command prompt, type: | ||
< | <syntaxhighlight lang="cpp">set PATH=%path%;yourPathToQt/bin; | ||
set QMAKESPEC=win32-msvc2005</ | set QMAKESPEC=win32-msvc2005</syntaxhighlight> | ||
# Type: designer | # Type: designer | ||
===QWidget is returned as the windows name on Windows, is there a way to change the windows name to make it unique?=== | ===QWidget is returned as the windows name on Windows, is there a way to change the windows name to make it unique?=== | ||
There is no direct way to achieve this. However if you apply the following patch: | There is no direct way to achieve this. However if you apply the following patch: | ||
< | <syntaxhighlight lang="cpp"> | ||
--- a/src/gui/kernel/qapplication_win.cpp | --- a/src/gui/kernel/qapplication_win.cpp | ||
+++ b/src/gui/kernel/qapplication_win.cpp | +++ b/src/gui/kernel/qapplication_win.cpp | ||
Line 10,173: | Line 9,994: | ||
// force CS_OWNDC when the GL graphics system is | // force CS_OWNDC when the GL graphics system is | ||
</ | </syntaxhighlight> | ||
then what you can do is call setObjectName() http://doc.qt.io/qt-5 | then what you can do is call setObjectName() http://doc.qt.io/qt-5/qobject.html#objectName-prop on the widgets and it well then ensure that it is registered as: | ||
< | <syntaxhighlight lang="cpp">QWidget_yourOwnNameHere</syntaxhighlight> | ||
There is a suggestion for adding this functionality in Jira http://bugreports.qt.io/browse/QTBUG-11487. | There is a suggestion for adding this functionality in Jira http://bugreports.qt.io/browse/QTBUG-11487. | ||
===Why do all Qt 4.7 applications crash when using Windows 7 x64 w/ VS 2010?=== | ===Why do all Qt 4.7 applications crash when using Windows 7 x64 w/ VS 2010?=== | ||
Line 10,191: | Line 10,012: | ||
http://support.microsoft.com/kb/2280741 | http://support.microsoft.com/kb/2280741 | ||
===Is there a way to know if a widget is currently using a stylesheet?=== | ===Is there a way to know if a widget is currently using a stylesheet?=== | ||
You can check if a widget has a stylesheet http://doc.qt.io/qt-5 | You can check if a widget has a stylesheet http://doc.qt.io/qt-5/stylesheet.html set by checking its QWidget::style() http://doc.qt.io/qt-5/qwidget.html#style value. | ||
If it has a stylesheet set, then the value returned will be QStyleSheetStyle. | If it has a stylesheet set, then the value returned will be QStyleSheetStyle. | ||
If you set a stylesheet on a parent widget however, then the child widgets will inherit the stylesheet, even though they don't have any properties that are specifically set for them in the stylesheet and the style returned for the children will be QStyleSheetStyle. So child widgets will implicitly have a stylesheet set when the parent has a stylesheet set. There is no Qt API for determening whether a child widget is mentioned in the parent widget's stylesheet, you would need to parse the stylesheet yourself to determine if that's the case. | If you set a stylesheet on a parent widget however, then the child widgets will inherit the stylesheet, even though they don't have any properties that are specifically set for them in the stylesheet and the style returned for the children will be QStyleSheetStyle. So child widgets will implicitly have a stylesheet set when the parent has a stylesheet set. There is no Qt API for determening whether a child widget is mentioned in the parent widget's stylesheet, you would need to parse the stylesheet yourself to determine if that's the case. | ||
===How can I add comments to a .ini file when using QSettings?=== | ===How can I add comments to a .ini file when using QSettings?=== | ||
QSettings http://doc.qt.io/qt-5 | QSettings http://doc.qt.io/qt-5/qsettings.html will overwrite the content of the INI file (and also writes the setting entries in alphabetical order), so any comments will be removed (and the ordering may not be what you expected it to be). | ||
The only way to be able to add comments is to implement ReadFunc http://doc.qt.io/qt-5/qsettings.html#ReadFunc-typedefand WriteFunc http://doc.qt.io/qt-5/qsettings.html#WriteFunc-typedef to suit your requirements, and register these functions to use with the format of your choice with registerFormat() http://doc.qt.io/qt-5/qsettings.html#registerFormat. | |||
===How can I detect in the .pro file if I am compiling for a 32 bit or a 64 bit platform?=== | ===How can I detect in the .pro file if I am compiling for a 32 bit or a 64 bit platform?=== | ||
You can use QMAKE_TARGET.arch to decide the platform you are building for. You can do it as follows: | You can use QMAKE_TARGET.arch to decide the platform you are building for. You can do it as follows: | ||
< | <syntaxhighlight lang="cpp"> | ||
win32-msvc*:contains(QMAKE_TARGET.arch, x86_64):{ | win32-msvc*:contains(QMAKE_TARGET.arch, x86_64):{ | ||
message( Building for 64 bit) | message( Building for 64 bit) | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I get a list of the widgets added to a layout?=== | ===How can I get a list of the widgets added to a layout?=== | ||
In order to get a list of the widgets added to a layout, then you can loop over the layout items using QLayout::count() http://doc.qt.io/qt-5/qlayout.html#count and QLayout::itemAt() http://doc.qt.io/qt-5/qlayout.html#itemAt and then if the the item is a QWidgetItem http://doc.qt.io/qt-5 | In order to get a list of the widgets added to a layout, then you can loop over the layout items using QLayout::count() http://doc.qt.io/qt-5/qlayout.html#count and QLayout::itemAt() http://doc.qt.io/qt-5/qlayout.html#itemAt and then if the the item is a QWidgetItem http://doc.qt.io/qt-5/qwidgetitem.html, you can add it's widget() http://doc.qt.io/qt-5/qwidgetitem.html#widget to a list. | ||
See the following example for an illustration: | See the following example for an illustration: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Widget : public QWidget | class Widget : public QWidget | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
Widget() | |||
{ | |||
QVBoxLayout *layout = new QVBoxLayout(this); | |||
QPushButton *button1 = new QPushButton(First button, this); | |||
button1->setObjectName(First); | |||
QPushButton *button2 = new QPushButton(Second button, this); | |||
button2->setObjectName(Second); | |||
QPushButton *button3 = new QPushButton(Third button, this); | |||
button3->setObjectName(Third); | |||
QPushButton *button4 = new QPushButton(Fourth button, this); | |||
button4->setObjectName(Fourth); | |||
layout->addWidget(button1); | |||
layout->addWidget(button2); | |||
layout->addWidget(button3); | |||
layout->addWidget(button4); | |||
for (int i = 0; i < layout->count();i++) { | |||
if (QWidgetItem *myItem = dynamic_cast <QWidgetItem*>(layout->itemAt(i))) { | |||
myList << myItem->widget(); | |||
}} | |||
for (int i = 0; i < myList.count(); i++) | |||
{ | |||
QWidget *wid = qobject_cast <QWidget*>(myList.at(i)); | |||
if (wid) | |||
qDebug() << wid->objectName(); | |||
}} | |||
private: | private: | ||
QList<QWidget*>myList; | |||
}; | }; | ||
Line 10,262: | Line 10,083: | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
Widget window; | |||
window.show(); | |||
return app.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I exclude user input for certain widgets when processing a long operation?=== | ===How can I exclude user input for certain widgets when processing a long operation?=== | ||
One approach could be to call | One approach could be to call | ||
< | <syntaxhighlight lang="cpp">setEnabled(false) </syntaxhighlight> | ||
on the widgets you want to exclude user input to, but this might cause some flashing in the GUI. Using a QProgressDialog http://doc.qt.io/qt-5 | on the widgets you want to exclude user input to, but this might cause some flashing in the GUI. Using a QProgressDialog http://doc.qt.io/qt-5/qprogressdialog.html could be another option. | ||
In situations where the approaches above are not suitable, then another approach to achieve this could be to reimplement the eventFilter() http://doc.qt.io/qt-5 | In situations where the approaches above are not suitable, then another approach to achieve this could be to reimplement the eventFilter() http://doc.qt.io/qt-5/qobject.html#eventFilter for your widget. Then you can set a flag when processing your event and check for this flag in the event filter. If the flag is set, you can simply return true and stop the event for the widgets you don't want the user to access. When the flag is not set, you can simply call the base class. | ||
The example below illustrates this approach. | The example below illustrates this approach. | ||
< | <syntaxhighlight lang="cpp">#include <QtWidgets> | ||
class Widget : public QWidget | class Widget : public QWidget | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
Widget() | |||
{ | |||
disableMe = false; | |||
QPushButton *button1 = new QPushButton(DISABLE ME, this); | |||
button2 = new QPushButton(CLICK ME, this); | |||
QVBoxLayout *layout = new QVBoxLayout(this); | |||
layout->addWidget(button1); | |||
layout->addWidget(button2); | |||
qApp->installEventFilter(this); | |||
QTimer::singleShot(1000, this, SLOT(test1())); | |||
connect(button1, SIGNAL(clicked()), this, SLOT(button1Slot())); | |||
connect(button2, SIGNAL(clicked()), this, SLOT(button2Slot())); | |||
} | |||
bool eventFilter(QObject *object, QEvent *event) | |||
{ | |||
if (object != button2 && disableMe) { | |||
if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick ) { | |||
return true; | |||
}} else { | |||
return QWidget::eventFilter(object, event); | |||
}} | |||
public slots: | |||
void test1() | |||
{ | |||
for (int i = 0; i < 10000; i++) { | |||
qDebug() << something; | |||
disableMe = true; | |||
qApp->processEvents(); | |||
} | |||
disableMe = false; | |||
} | |||
void button1Slot() | |||
{ | |||
qDebug() << 1111111111111111111111111111111111111111111111111111111111; | |||
} | |||
void button2Slot() | |||
{ | |||
qDebug() << 222222222222222222222222222222222222222222222222222222222222; | |||
} | |||
private: | private: | ||
QPushButton *button2; | |||
bool disableMe; | |||
}; | }; | ||
Line 10,341: | Line 10,162: | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
Widget window; | |||
window.show(); | |||
return app.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
===Why does the memory keep increasing when repeatedly pasting text and calling clear() in a QLineEdit?=== | ===Why does the memory keep increasing when repeatedly pasting text and calling clear() in a QLineEdit?=== | ||
When calling QLineEdit::clear() http://doc.qt.io/qt-5 | When calling QLineEdit::clear() http://doc.qt.io/qt-5/qlineedit.html#clear, the linedit is storing the text in the undo/redo buffer and therefore the memory usage will increase as that increases. | ||
To get around this, you can call | To get around this, you can call | ||
< | <syntaxhighlight lang="cpp">QLineEdit::setText( ) </syntaxhighlight> | ||
instead. In this case, the undo/redo history will be cleared and you will not get a memory increase | instead. In this case, the undo/redo history will be cleared and you will not get a memory increase | ||
===Is it possible to move the Qt directory to another directory after installation?=== | ===Is it possible to move the Qt directory to another directory after installation?=== | ||
When Qt is installed, the path is hardcoded into the Qt binaries, therefore it will not work to move it to another directory out of the box. You can however create a qt.conf http://doc.qt.io/qt-5 | When Qt is installed, the path is hardcoded into the Qt binaries, therefore it will not work to move it to another directory out of the box. You can however create a qt.conf http://doc.qt.io/qt-5/qt-conf.html file and override the hard-coded paths that are compiled into the Qt library there. | ||
This way the paths from the qt.conf file will be used instead of the ones hardcoded into the Qt binaries. | This way the paths from the qt.conf file will be used instead of the ones hardcoded into the Qt binaries. | ||
Line 10,368: | Line 10,189: | ||
The usage is: | The usage is: | ||
< | <syntaxhighlight lang="cpp">qpatch files-to-patch-windows oldQtDir newQtDir</syntaxhighlight> | ||
===How can I prevent the font from scaling up when the DPI is increased?=== | ===How can I prevent the font from scaling up when the DPI is increased?=== | ||
In order to prevent the font size from increasing when the DPI is increased then you can call | In order to prevent the font size from increasing when the DPI is increased then you can call | ||
< | <syntaxhighlight lang="cpp">setPixelSize(theSizeYouNeed) </syntaxhighlight> | ||
on your font and set this to be the application's font. This will ensure that the font will not scale with the DPI. See the documentation on setPixelSize() http://doc.qt.io/qt-5/qfont.html#setPixelSize | on your font and set this to be the application's font. This will ensure that the font will not scale with the DPI. See the documentation on setPixelSize() http://doc.qt.io/qt-5/qfont.html#setPixelSize | ||
Line 10,380: | Line 10,201: | ||
The following example illustrates this approach: | The following example illustrates this approach: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char *argv[]) | int main(int argc, char *argv[]) | ||
Line 10,389: | Line 10,210: | ||
font.setPixelSize(8); | font.setPixelSize(8); | ||
qApp->setFont(font); | qApp->setFont(font); | ||
QLabel label("Resolution dependent."); | QLabel label("Resolution dependent."); | ||
label.show(); | label.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I control whether a widget gets a focus frame or not on Mac?=== | ===How can I control whether a widget gets a focus frame or not on Mac?=== | ||
Some widgets will have a focus frame by default on Mac when the widget gets focus, for example QListView http://doc.qt.io/qt-5 | Some widgets will have a focus frame by default on Mac when the widget gets focus, for example QListView http://doc.qt.io/qt-5/qlistview.html and QLineEdit http://doc.qt.io/qt-5/qlineedit.html, whereas some will not get a focus frame, for example QTextEdit http://doc.qt.io/qt-5/qtextedit.html. In order to change when this occurs there is an attribute that can be used - WA_MacShowFocusFrame http://doc.qt.io/qt-5/qt.html#WidgetAttribute-enum. If you want a widget to have a frame then you can call: | ||
< | <syntaxhighlight lang="cpp"> | ||
widget->setAttribute(Qt::WA_MacShowFocusFrame); | widget->setAttribute(Qt::WA_MacShowFocusFrame); | ||
</ | </syntaxhighlight> | ||
to turn it off. It is just a case of passing false as the second argument like: | to turn it off. It is just a case of passing false as the second argument like: | ||
< | <syntaxhighlight lang="cpp"> | ||
widget->setAttribute(Qt::WA_MacShowFocusFrame, false); | widget->setAttribute(Qt::WA_MacShowFocusFrame, false); | ||
</ | </syntaxhighlight> | ||
===What are the minimum hardware requirements for Qt on the desktop?=== | ===What are the minimum hardware requirements for Qt on the desktop?=== | ||
We do not provide an official minimum hardware requirement list for Qt on the desktop, since it varies a lot on the the compiler used, the configuration and how you use Qt in your application. | We do not provide an official minimum hardware requirement list for Qt on the desktop, since it varies a lot on the the compiler used, the configuration and how you use Qt in your application. | ||
===Is there any way to compile the Qt source code and Qt applications with /clr flag?=== | ===Is there any way to compile the Qt source code and Qt applications with /clr flag?=== | ||
Line 10,418: | Line 10,239: | ||
===Why is the warning QObject::startTimer: timers cannot be started from another thread issued when my worker thread is running?=== | ===Why is the warning QObject::startTimer: timers cannot be started from another thread issued when my worker thread is running?=== | ||
The QThread http://doc.qt.io/qt-5 | The QThread http://doc.qt.io/qt-5/qthread.html class instance, like all QObject http://doc.qt.io/qt-5/qobject.html instances, lives in the thread in which you create it. The signals, slots and members of the custom thread will hence also belong to the thread where the custom thread was created and not to the custom thread itself. | ||
In order for the signals, slots and members to have the right context/belong to the right thread, you should create a QObject subclass that contains this logic instead of a QThread subclass and simply instantiate an instance of this QObject subclass instead. QThread has a started() http://doc.qt.io/qt-5 | In order for the signals, slots and members to have the right context/belong to the right thread, you should create a QObject subclass that contains this logic instead of a QThread subclass and simply instantiate an instance of this QObject subclass instead. QThread has a started() http://doc.qt.io/qt-5/qthread.html#started signal that you can connect to when you need to perform some initialization. To actually have your code run in the new thread context, you need to instantiate a QThread and assign your object to that thread using the moveToThread() http://doc.qt.io/qt-5/qobject.html#moveToThread function. This will ensure that the members get the custom thread as the context and not the GUI thread. | ||
The following blog http://blog.qt.io/2010/06/17/youre-doing-it-wrong/ is written by one of the developers who created the threading classes and he suggests using the pattern explained above to get the right result. | The following blog http://blog.qt.io/2010/06/17/youre-doing-it-wrong/ is written by one of the developers who created the threading classes and he suggests using the pattern explained above to get the right result. | ||
===How can I add buttons to the tabs of a QTabBar instead of having an icon/string?=== | ===How can I add buttons to the tabs of a QTabBar instead of having an icon/string?=== | ||
It is not possible to add widgets to the tabbar (other than the close(x) button). Instead of using a QTabBar http://doc.qt.io/qt-5 | It is not possible to add widgets to the tabbar (other than the close(x) button). Instead of using a QTabBar http://doc.qt.io/qt-5/qtabbar.html though, you could create a QWidget http://doc.qt.io/qt-5/qwidget.html that has the buttons in it and then you can make them all toggle buttons. That way when one is pushed then it can be used to change which widget is shown. | ||
The example below illustrates how this can be done by subclassing QWidget and using a QButtonGroup http://doc.qt.io/qt-5 | The example below illustrates how this can be done by subclassing QWidget and using a QButtonGroup http://doc.qt.io/qt-5/qbuttongroup.htmlto help with the exclusivity feature. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class MyTabWidget : public QWidget | class MyTabWidget : public QWidget | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
MyTabWidget(QWidget *parent = nullptr) : QWidget(parent) | |||
{ | |||
QHBoxLayout *buttonsLayout = new QHBoxLayout; | |||
buttonsLayout->setSpacing(0); | |||
buttonsLayout->setMargin(0); | |||
QButtonGroup *group = new QButtonGroup(this); | |||
QPixmap pix(16, 16); | |||
pix.fill(Qt::red); | |||
QToolButton *button = new QToolButton; | |||
button->setIcon(QIcon(pix)); | |||
button->setCheckable(true); | |||
buttonsLayout->addWidget(button); | |||
group->addButton(button, 0); | |||
pix.fill(Qt::blue); | |||
button = new QToolButton; | |||
button->setIcon(QIcon(pix)); | |||
button->setCheckable(true); | |||
buttonsLayout->addWidget(button); | |||
group->addButton(button, 1); | |||
pix.fill(Qt::green); | |||
button = new QToolButton; | |||
button->setIcon(QIcon(pix)); | |||
button->setCheckable(true); | |||
buttonsLayout->addWidget(button); | |||
buttonsLayout->addSpacing(100); | |||
group->addButton(button, 2); | |||
group->setExclusive(true); | |||
connect(group, SIGNAL(buttonClicked(int)), this, SLOT(changeCurrent(int))); | |||
stackedWidget = new QStackedWidget; | |||
QLabel *red = new QLabel(This is the red widget); | |||
QLabel *blue = new QLabel(This is the blue widget); | |||
QLabel *green = new QLabel(This is the green widget); | |||
stackedWidget->addWidget(red); | |||
stackedWidget->addWidget(blue); | |||
stackedWidget->addWidget(green); | |||
QVBoxLayout *vbox = new QVBoxLayout; | |||
vbox->addLayout(buttonsLayout); | |||
vbox->addWidget(stackedWidget); | |||
setLayout(vbox); | |||
} | |||
public slots: | |||
void changeCurrent(int idx) | |||
{ | |||
stackedWidget->setCurrentIndex(idx); | |||
} | |||
private: | private: | ||
QStackedWidget *stackedWidget; | |||
}; | }; | ||
Line 10,495: | Line 10,316: | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication a(argc, argv); | |||
MyTabWidget tw; | |||
tw.show(); | |||
return a.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I expand all children of a specific modelindex in a QTreeView?=== | ===How can I expand all children of a specific modelindex in a QTreeView?=== | ||
Line 10,510: | Line 10,331: | ||
The example below illustrates how you can implement this functionality yourself. | The example below illustrates how you can implement this functionality yourself. | ||
< | <syntaxhighlight lang="cpp">#include <QtWidgets> | ||
class TreeView : public QTreeView | class TreeView : public QTreeView | ||
{ | { | ||
public: | public: | ||
TreeView() | |||
{ | |||
QStandardItemModel *model = new QStandardItemModel(this); | |||
QStandardItem *parentItem = model->invisibleRootItem(); | |||
QStandardItem *myItem = new QStandardItem(child); | |||
parentItem->appendRow(myItem); | |||
QStandardItem *grandChild = new QStandardItem(hi); | |||
myItem->appendRow(grandChild); | |||
for (int i = 0; i < 200; ++i) { | |||
QStandardItem *item = new QStandardItem(QString(item %0).arg(i)); | |||
grandChild->appendRow(item); | |||
item->appendRow(new QStandardItem(QString(foo %0).arg(i))); | |||
} | |||
for (int i = 0; i < 4; ++i) { | |||
QStandardItem *item = new QStandardItem(QString(item %0).arg(i)); | |||
myItem->appendRow(item); | |||
} | |||
for (int i = 0; i < 4; ++i) { | |||
QStandardItem *item = new QStandardItem(QString(item %0).arg(i)); | |||
parentItem->appendRow(item); | |||
parentItem = item; | |||
} | |||
setModel(model); | |||
expandIt(model->indexFromItem(myItem)); | |||
} | |||
public : | public : | ||
void expandIt(QModelIndex myIndex) | |||
{ | |||
if (myIndex.isValid()) { | |||
expand(myIndex); | |||
} | |||
QModelIndex nextIndex = indexBelow(myIndex); | |||
while (nextIndex.isValid()){ | |||
if (myIndex.parent() == nextIndex.parent()) | |||
break; | |||
expand(nextIndex); | |||
nextIndex = indexBelow(nextIndex); | |||
}}}; | |||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
TreeView window; | |||
window.show(); | |||
return app.exec(); | |||
}</syntaxhighlight> | |||
===How to upgrade Qt on Windows?=== | ===How to upgrade Qt on Windows?=== | ||
Line 10,575: | Line 10,396: | ||
4) Install Qt vs-addin -- It automatically uninstalls the previous release | 4) Install Qt vs-addin -- It automatically uninstalls the previous release | ||
5) Update any instances of the Qt directory in your PATH environment variable | 5) Update any instances of the Qt directory in your PATH environment variable | ||
6) Clean all your projects by typing | 6) Clean all your projects by typing | ||
< | <syntaxhighlight lang="cpp">nmake distclean (if using Visual Studio) | ||
mingw32-make distclean (if using MinGW)</ | mingw32-make distclean (if using MinGW)</syntaxhighlight> | ||
in your projects directories in the command prompt provided with Qt in the Start menu | in your projects directories in the command prompt provided with Qt in the Start menu | ||
Line 10,585: | Line 10,406: | ||
8) Build all | 8) Build all | ||
9) If moc, your application, or other tools fail with side-by-side errors, check the System or Application events for details (Control Panel | Administrative Tools | Event Viewer). You are probably missing a dll and need to install a Microsoft update. If that doesn't work, use Dependency Walker (depends.exe) to locate the missing dll. | 9) If moc, your application, or other tools fail with side-by-side errors, check the System or Application events for details (Control Panel | Administrative Tools | Event Viewer). You are probably missing a dll and need to install a Microsoft update. If that doesn't work, use Dependency Walker (depends.exe) to locate the missing dll. | ||
===How can I have multiple rows in a QTabBar?=== | ===How can I have multiple rows in a QTabBar?=== | ||
Qt does not provide a function that allows the tabs of a QTabBar http://doc.qt.io/qt-5 | Qt does not provide a function that allows the tabs of a QTabBar http://doc.qt.io/qt-5/qtabbar.html to be arranged in multiple rows instead of one line and buttons to scroll the tabs. However, by reimplementing paintEvent() http://doc.qt.io/qt-5/qtabbar.html#paintEvent, mousePressEvent() http://doc.qt.io/qt-5/qtabbar.html#mousePressEvent and resizeEvent() http://doc.qt.io/qt-5/qtabbar.html#resizeEvent of the QTabBar class, one can get this functionality. | ||
The attached example illustrates how this can be done. It leaves one problem open though, which is that only tabs in the first row will be highlighted when hovering over it. | The attached example illustrates how this can be done. It leaves one problem open though, which is that only tabs in the first row will be highlighted when hovering over it. | ||
Line 10,594: | Line 10,415: | ||
See also the following report http://bugreports.qt.io/browse/QTBUG-2061 in the Bug Tracker. | See also the following report http://bugreports.qt.io/browse/QTBUG-2061 in the Bug Tracker. | ||
===How to toggle antialiasing for SVG rendering?=== | ===How to toggle antialiasing for SVG rendering?=== | ||
Qt's SVG module http://doc.qt.io/qt-5 | Qt's SVG module http://doc.qt.io/qt-5/qtsvg.html hardcodes antialiasing on, because this is what makes sense most of the time. | ||
To be able to use rendering hints when rendering svg, one could use QtWebKit http://doc.qt.io/qt-5 | To be able to use rendering hints when rendering svg, one could use QtWebKit http://doc.qt.io/qt-5/qtwebkit.html and rely on the shape-rendering style property defined in the SVG specification http://www.w3.org/TR/SVG11/painting.html#RenderingProperties. | ||
Here's an example: | Here's an example: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
#include <QtWebKit> | #include <QtWebKit> | ||
Line 10,612: | Line 10,433: | ||
public: | public: | ||
DemoWidget(QWidget *parent = | DemoWidget(QWidget *parent = nullptr) : QWidget(parent) | ||
, m_currentPage(0) | , m_currentPage(0) | ||
, m_widthSelector(new QSpinBox(this)) | , m_widthSelector(new QSpinBox(this)) | ||
Line 10,736: | Line 10,557: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===When using jom I get an error stating the script file could not be created. How do I fix this?=== | ===When using jom I get an error stating the script file could not be created. How do I fix this?=== | ||
If you get something like the following error when running jom: | If you get something like the following error when running jom: | ||
< | <syntaxhighlight lang="cpp"> Error: Can't create command script file</syntaxhighlight> | ||
Then this can be caused by the fact that the* %TMP% *directory on your system is marked as read only even though you can write to it. This is related to a problem with Windows this article http://support.microsoft.com/kb/326549/en-us o has more information about. If you unmark the read-only flag then this should solve the problem. | Then this can be caused by the fact that the* %TMP% *directory on your system is marked as read only even though you can write to it. This is related to a problem with Windows this article http://support.microsoft.com/kb/326549/en-us o has more information about. If you unmark the read-only flag then this should solve the problem. | ||
===How to allow an application to only access webpages from a certain host?=== | ===How to allow an application to only access webpages from a certain host?=== | ||
The attached example illustrates how you can subclass QNetworkAccessManager http://doc.qt.io/qt-5 | The attached example illustrates how you can subclass QNetworkAccessManager http://doc.qt.io/qt-5/qnetworkaccessmanager.html and reimplement createRequest() http://doc.qt.io/qt-5/qnetworkaccessmanager.html#createRequest to control which webpages that are shown. | ||
===How can I enable autoscrolling when dragging near the edges in a QScrollArea?=== | ===How can I enable autoscrolling when dragging near the edges in a QScrollArea?=== | ||
The attached example is a modified version of the qtVersion/examples/draganddrop/draggabletext example, where autoscrolling has been implemented. The autoScroll() function in the example checks whether we are dragging within the autoscroll margins and modifies the values of the scrollbars accordingly using setValue() http://doc.qt.io/qt-5/qabstractslider.html#value-prop. | The attached example is a modified version of the qtVersion/examples/draganddrop/draggabletext example, where autoscrolling has been implemented. The autoScroll() function in the example checks whether we are dragging within the autoscroll margins and modifies the values of the scrollbars accordingly using setValue() http://doc.qt.io/qt-5/qabstractslider.html#value-prop. | ||
Then in the dragMoveEvent(), we simply call the autoScroll() function. | Then in the dragMoveEvent(), we simply call the autoScroll() function. | ||
===How can I sort a view by locale?=== | ===How can I sort a view by locale?=== | ||
You can set a QSortFilterProxyModel http://doc.qt.io/qt-5 | You can set a QSortFilterProxyModel http://doc.qt.io/qt-5/qsortfilterproxymodel.html on your view and call setSortLocaleAware() http://doc.qt.io/qt-5/qsortfilterproxymodel.html#isSortLocaleAware-prop on the proxy model. | ||
If you are not using a QTableView http://doc.qt.io/qt-5 | If you are not using a QTableView http://doc.qt.io/qt-5/qtableview.html or QTreeView http://doc.qt.io/qt-5/qtreeview.html, but a convenience class like QTableWidget http://doc.qt.io/qt-5/qtablewidget.html, then you need to subclass QTableWidgetItem http://doc.qt.io/qt-5/qtablewidgetitem.html and reimplement QTableWidgetItem::operator<() http://doc.qt.io/qt-5/qtablewidgetitem.html#operator-lt to perform sorting based on the locale. | ||
You could use QString::localeAwareCompare() http://doc.qt.io/qt-5/qstring.html#localeAwareCompare-2 for the comparison, | You could use QString::localeAwareCompare() http://doc.qt.io/qt-5/qstring.html#localeAwareCompare-2 for the comparison, | ||
i.e something like | i.e something like | ||
< | <syntaxhighlight lang="cpp">bool operator< (const QTableWidgetItem &other) const | ||
{ | { | ||
... | ... | ||
return (text().localeAwareCompare(other.text()) < 0); | return (text().localeAwareCompare(other.text()) < 0); | ||
... | ... | ||
}</ | }</syntaxhighlight> | ||
===How can I add spaces between the columns in a QTableWidget?=== | ===How can I add spaces between the columns in a QTableWidget?=== | ||
In order to get the spacing between the columns in the header, then you can set a stylesheet http://doc.qt.io/qt-5 | In order to get the spacing between the columns in the header, then you can set a stylesheet http://doc.qt.io/qt-5/stylesheet.html like the following: | ||
< | <syntaxhighlight lang="cpp">setStyleSheet(QHeaderView::section:horizontal {margin-right: 2; border: 1px solid});</syntaxhighlight> | ||
To get the spacing between the cells, you can subclass your view, call | To get the spacing between the cells, you can subclass your view, call | ||
< | <syntaxhighlight lang="cpp">setShowGrid(false)</syntaxhighlight> | ||
iterate over its columns and rows and draw the grid yourself with the size you need. The example below illustrates this approach: | iterate over its columns and rows and draw the grid yourself with the size you need. The example below illustrates this approach: | ||
< | <syntaxhighlight lang="cpp">#include <QtWidgets> | ||
class TableWidget : public QTableWidget | class TableWidget : public QTableWidget | ||
{ | { | ||
Line 10,805: | Line 10,626: | ||
QPainter painter(viewport()); | QPainter painter(viewport()); | ||
int myHeight = horizontalHeader()->height(); | int myHeight = horizontalHeader()->height(); | ||
int i = 0; | int i = 0; | ||
for (i = 0; i < columnCount(); i++) { | for (i = 0; i < columnCount(); i++) { | ||
int startPos = horizontalHeader()->sectionViewportPosition(i); | int startPos = horizontalHeader()->sectionViewportPosition(i); | ||
Line 10,816: | Line 10,637: | ||
painter.drawLine(myFrom, myTo); | painter.drawLine(myFrom, myTo); | ||
} | } | ||
for (i = 0; i < rowCount(); i++) { | for (i = 0; i < rowCount(); i++) { | ||
int startPos = verticalHeader()->sectionViewportPosition(i); | int startPos = verticalHeader()->sectionViewportPosition(i); | ||
QPoint myFrom = QPoint(0, startPos); | QPoint myFrom = QPoint(0, startPos); | ||
Line 10,836: | Line 10,657: | ||
table.show(); | table.show(); | ||
return app.exec(); | return app.exec(); | ||
}</ | }</syntaxhighlight> | ||
===How can I cross-compile Qt/Embedded with Phonon support?=== | ===How can I cross-compile Qt/Embedded with Phonon support?=== | ||
Line 10,863: | Line 10,684: | ||
When configuring Qt, just ensure that you have the options: | When configuring Qt, just ensure that you have the options: | ||
< | <syntaxhighlight lang="cpp">-glib -phonon -phonon-backend</syntaxhighlight> | ||
included so that Phonon is configured for in this build of Qt. | included so that Phonon is configured for in this build of Qt. | ||
==="Why do I get the error QPrintDialog: Cannot be used on non-native printers when printing to PDF using QPrintDialog?"=== | ==="Why do I get the error QPrintDialog: Cannot be used on non-native printers when printing to PDF using QPrintDialog?"=== | ||
QPrintDialog http://doc.qt.io/qt-5 | QPrintDialog http://doc.qt.io/qt-5/qprintdialog.html can�� be used to print to PDFs on Windows, because on Windows a native print dialog is used and it has no knowledge of Qt�� PDF printer. | ||
===Why don't I get a vertical scrollbar when my table has 1 row and only parts of the row is shown?=== | ===Why don't I get a vertical scrollbar when my table has 1 row and only parts of the row is shown?=== | ||
The default scrollMode http://doc.qt.io/qt-5 | The default scrollMode http://doc.qt.io/qt-5/qabstractitemview.html#ScrollMode-enum is set to QAbstractItemView::ScrollPerItem by default. So, when you only have one row it decides it does not need a scrollbar. Setting the scrollMode to QAbstractItemView::ScrollPerPixel should cause a scrollbar to show up also when having just one row. | ||
===Why don't the QDir functions accept files that begin with ':' ?=== | ===Why don't the QDir functions accept files that begin with ':' ?=== | ||
This is because the colon as the first character in a filename is reserved for our resource model, and we cannot change that. QDir::remove() http://doc.qt.io/qt-5 | This is because the colon as the first character in a filename is reserved for our resource model, and we cannot change that. QDir::remove() http://doc.qt.io/qt-5/qdir.html#remove for example will delete files starting with if passed an absolute path, but not a relative one. Instead you can try prepending ./ to your relative filename, that should make it work. | ||
===How can I programatically uncheck all buttons that have autoExclusive set to true?=== | ===How can I programatically uncheck all buttons that have autoExclusive set to true?=== | ||
When the autoExclusive http://doc.qt.io/qt-5 | When the autoExclusive http://doc.qt.io/qt-5/qabstractbutton.html#autoExclusive-prop property is enabled, checkable buttons that belong to the same parent widget behave as if they were part of the same exclusive button group. In an exclusive group, the user cannot uncheck the currently checked button by clicking on it; instead, another button in the group must be clicked to set the new checked button for that group. The same is true when unchecking the button programmatically. | ||
To get around this, then you can e.g enable and disable the autoexclusive property for the currently checked button. See the following example for an illustration: | To get around this, then you can e.g enable and disable the autoexclusive property for the currently checked button. See the following example for an illustration: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Widget : public QWidget | class Widget : public QWidget | ||
{ | { | ||
Line 10,896: | Line 10,717: | ||
layout->addWidget(button2); | layout->addWidget(button2); | ||
layout->addWidget(button3); | layout->addWidget(button3); | ||
button1->setCheckable(true); | button1->setCheckable(true); | ||
button1->setAutoExclusive(true); | button1->setAutoExclusive(true); | ||
button2->setCheckable(true); | button2->setCheckable(true); | ||
button2->setAutoExclusive(true); | button2->setAutoExclusive(true); | ||
button3->setCheckable(true); | button3->setCheckable(true); | ||
button3->setAutoExclusive(true); | button3->setAutoExclusive(true); | ||
button3->setChecked(true); | button3->setChecked(true); | ||
QTimer::singleShot(1000, this, SLOT(testSlot())); | QTimer::singleShot(1000, this, SLOT(testSlot())); | ||
} | } | ||
public slots: | public slots: | ||
Line 10,931: | Line 10,752: | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Is there a way that Qt can open a window containing a PDF file? === | ===Is there a way that Qt can open a window containing a PDF file? === | ||
You have the following alternatives: | You have the following alternatives: | ||
Line 10,937: | Line 10,758: | ||
# This Qt Quarterly article http://doc.qt.io/qt-5/qq/qq27-poppler.html outlines how you can do this using the 3rd party application Poppler. | # This Qt Quarterly article http://doc.qt.io/qt-5/qq/qq27-poppler.html outlines how you can do this using the 3rd party application Poppler. | ||
# You can use QDesktopServices::openUrl() http://doc.qt.io/qt-5/4.7/qdesktopservices.html#openUrl | # You can use QDesktopServices::openUrl() http://doc.qt.io/qt-5/4.7/qdesktopservices.html#openUrl | ||
# You can use ActiveQt http://doc.qt.io/qt-5 | # You can use ActiveQt http://doc.qt.io/qt-5/qt-activex.html to show a QAXWidget that represents an Adobe reader window and thus load the PDF into that. | ||
Line 10,943: | Line 10,764: | ||
You can use a dummy action for the title where you set the action to be disabled and then paint it in the enabled color. The example below illustrates this approach. | You can use a dummy action for the title where you set the action to be disabled and then paint it in the enabled color. The example below illustrates this approach. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class MyWidget : public QWidget | class MyWidget : public QWidget | ||
{ | { | ||
public: MyWidget( QWidget * parent = | public: MyWidget(QWidget * parent = nullptr) : QWidget (parent) | ||
{ | |||
QVBoxLayout *layout = new QVBoxLayout(this); | |||
QPushButton *button = new QPushButton(Button); | |||
QMenu *menu = new QMenu(Menu); | |||
QPalette pal = menu->palette(); | |||
pal.setColor(QPalette::Disabled, QPalette::Text, pal.color(QPalette::Active, QPalette::Text)); | |||
QAction *action = new QAction(this); | |||
menu->setPalette(pal); | |||
action->setText(Title); | |||
action->setEnabled(false); | |||
menu->addAction(action); | |||
menu->addSeparator(); | |||
menu->addAction(Action 1); | |||
menu->addAction(Action 2); | |||
menu->addSeparator(); | |||
menu->addAction(Action 3); | |||
button->setMenu(menu); | |||
layout->addWidget(button); | |||
}}; | |||
int main(int argc, char *argv[]) | |||
{ | |||
QApplication app(argc, argv); | |||
MyWidget widget; | |||
widget.show(); | |||
return app.exec(); | |||
} | |||
</ | </syntaxhighlight> | ||
===Is it possible to modify the titlebar in a QDockWidget?=== | ===Is it possible to modify the titlebar in a QDockWidget?=== | ||
The titlebar is privately implemented when the QDockWidget is docked. When the dockwidget is floating, it is using the native titlebar as documented here http://doc.qt.io/qt-5 | The titlebar is privately implemented when the QDockWidget is docked. When the dockwidget is floating, it is using the native titlebar as documented here http://doc.qt.io/qt-5/qdockwidget.html#setTitleBarWidget | ||
You have no control over the native titlebar, so you can�� modify the titlebar when the dockwidget is floating. If you need to do so, then you need to create a custom titlebar using setTitleBarWidget() from the link above. | You have no control over the native titlebar, so you can�� modify the titlebar when the dockwidget is floating. If you need to do so, then you need to create a custom titlebar using setTitleBarWidget() from the link above. | ||
If you only need to modify the titlebar when the QDockWidget is docked however, you can modify it using the style. See the documentation on QStyle::CC_TitleBar http://doc.qt.io/qt-5 | If you only need to modify the titlebar when the QDockWidget is docked however, you can modify it using the style. See the documentation on QStyle::CC_TitleBar http://doc.qt.io/qt-5/qstyle.html#ComplexControl-enum | ||
===What is the usage of the qtlibinfix and qtnamespace configuration options?=== | ===What is the usage of the qtlibinfix and qtnamespace configuration options?=== | ||
qtnamespace http://doc.qt.io/qt-5 | qtnamespace http://doc.qt.io/qt-5/configure-options.html compiles Qt into a namespace and qtlibinfix modifies the names of the Qt dlls. | ||
For example: qtlibinfix renames all the Qt dlls with the infix you have chosen: | For example: qtlibinfix renames all the Qt dlls with the infix you have chosen: | ||
< | <syntaxhighlight lang="cpp">configure -qtlibinfix CustomName</syntaxhighlight> | ||
will result in the Qt dlls having names like QtGuiCustomName.dll. | will result in the Qt dlls having names like QtGuiCustomName.dll. | ||
qtnamespace wraps all of the Qt code in the namespace you have chosen, e.g: | qtnamespace wraps all of the Qt code in the namespace you have chosen, e.g: | ||
< | <syntaxhighlight lang="cpp">configure -qtnamespace CustomName</syntaxhighlight> | ||
so that you would be writing code like | so that you would be writing code like | ||
< | <syntaxhighlight lang="cpp">CustomName::QWidget *widget = new CustomName::QWidget;</syntaxhighlight> | ||
as a result. | as a result. | ||
===How can I use a QObject (subclass) in qml?=== | ===How can I use a QObject (subclass) in qml?=== | ||
The QML engine has no intrinsic knowledge of any class types. Instead the programmer must register the C++ types with their corresponding QML names. This can be done using qmlRegisterType() http://doc.qt.io/qt-5 | The QML engine has no intrinsic knowledge of any class types. Instead the programmer must register the C++ types with their corresponding QML names. This can be done using qmlRegisterType() http://doc.qt.io/qt-5/qdeclarativeengine.html#qmlRegisterType. When having registered the type, you can use it in qml as shown in the following example: | ||
*main.cpp* | *main.cpp* | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
#include <QDeclarativeEngine> | #include <QDeclarativeEngine> | ||
#include <QDeclarativeView> | #include <QDeclarativeView> | ||
Line 11,016: | Line 10,837: | ||
class MyObject : public QObject | class MyObject : public QObject | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
MyObject() | |||
{} | |||
public slots: | |||
QObject * getObject() | |||
{ | |||
return new MyObject(); | |||
} | |||
}; | }; | ||
Line 11,031: | Line 10,852: | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
QDeclarativeView view; | |||
qmlRegisterType<MyObject>(QtQuick, 1, 0, MyObject); | |||
view.setSource(QUrl::fromLocalFile(c:/testOwnership/test.qml)); | |||
view.show(); | |||
return app.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
*test.qml* | *test.qml* | ||
< | <syntaxhighlight lang="cpp"> | ||
import QtQuick 1.0 | import QtQuick 1.0 | ||
Line 11,054: | Line 10,875: | ||
{ | { | ||
id: myObject | id: myObject | ||
Component.onCompleted: { | |||
print(completed... + myObject.getInfo); | |||
var obj = myObject.getInfo(); | |||
}}} | |||
</ | </syntaxhighlight> | ||
===How can I ensure that the widgets in my touch screen application have a minimum size?=== | ===How can I ensure that the widgets in my touch screen application have a minimum size?=== | ||
You can use QApplication::setGlobalStrut() http://doc.qt.io/qt-5 | You can use QApplication::setGlobalStrut() http://doc.qt.io/qt-5/qapplication.html#globalStrut-prop for this. This function sets the minimum size a widget can be, and is helpful when making an application more touch screen friendly. | ||
===Why does Qt uses 0 instead of NULL in its code?=== | ===Why does Qt uses 0 instead of NULL in its code?=== | ||
This is just a matter of coding style. Qt code uses 0 because it is more c++ like than NULL. If you wish to use NULL in your code however, that's fine. | This is just a matter of coding style. Qt code uses 0 because it is more c++ like than NULL. If you wish to use NULL in your code however, that's fine. | ||
Line 11,072: | Line 10,893: | ||
===How can we reference dynamically created objects in qml?=== | ===How can we reference dynamically created objects in qml?=== | ||
The standard way of referencing an object in qml is through its id() http://doc.qt.io/qt-5 | The standard way of referencing an object in qml is through its id() http://doc.qt.io/qt-5/qdeclarativeintroduction.html#object-identifiers value. It is not possible to assign an id to an object however, so the id can't be used for referencing dynamically created objects. The id is part of the parsing context of the .qml file and only available inside that .qml file. The id is not accessible through JS or C++. | ||
What you can do instead, is to create a property variant variable and then assign the javascript object to that variable. Something like: | What you can do instead, is to create a property variant variable and then assign the javascript object to that variable. Something like: | ||
< | <syntaxhighlight lang="cpp">property variant foo; | ||
onSomethingHappened: { | onSomethingHappened: { | ||
theObject = getMeTheObject(); | theObject = getMeTheObject(); | ||
foo = theObject; | foo = theObject; | ||
} | } | ||
</ | </syntaxhighlight> | ||
lets you access a JS created object as if it had been named, through a member property. | lets you access a JS created object as if it had been named, through a member property. | ||
===How can I disable compilation of some code for a certain platform?=== | ===How can I disable compilation of some code for a certain platform?=== | ||
You can use one of the global macros http://doc.qt.io/qt-5 | You can use one of the global macros http://doc.qt.io/qt-5/qtglobal.html to determine which OS you are compiling for. The following code for example: | ||
< | <syntaxhighlight lang="cpp">// OS is not Windows | ||
#ifndef Q_OS_WIN32 | #ifndef Q_OS_WIN32 | ||
// execute code | // execute code | ||
</ | </syntaxhighlight> | ||
will only be compiled on non-Windows platforms. | will only be compiled on non-Windows platforms. | ||
===How should I start learning Qt?=== | ===How should I start learning Qt?=== | ||
The easiest way to learn Qt is to install the Qt SDK http://www.qt.io/product/ and try out one of the many examples/demos/tutorials. It comes with a dedicated IDE called Qt Creator http://www.qt.io/product/ that gets you going with Qt in an instant. | The easiest way to learn Qt is to install the Qt SDK http://www.qt.io/product/ and try out one of the many examples/demos/tutorials. It comes with a dedicated IDE called Qt Creator http://www.qt.io/product/ that gets you going with Qt in an instant. | ||
It can also be helpful to take a look at the official Get Started guide http://doc.qt.io/qt-5/qt-4.7/gettingstartedqt.html in the Qt documentation. Also, the Qt Developer Network (this site) has a wiki, a broad selection of eLearning videos [developer.qt.nokia.com] and other resources that you can use. | It can also be helpful to take a look at the official Get Started guide http://doc.qt.io/qt-5/qt-4.7/gettingstartedqt.html in the Qt documentation. Also, the Qt Developer Network (this site) has a wiki, a broad selection of eLearning videos [developer.qt.nokia.com] and other resources that you can use. | ||
Line 11,104: | Line 10,925: | ||
If you would like class room based Qt training there are a variety of courses being held by Qt partners around the world every month. Schedule and course info can be found here http://qt.nokia.com/partners/training/course-schedule. | If you would like class room based Qt training there are a variety of courses being held by Qt partners around the world every month. Schedule and course info can be found here http://qt.nokia.com/partners/training/course-schedule. | ||
===How can I add tooltips to actions in menus?=== | ===How can I add tooltips to actions in menus?=== | ||
Qt does not support tooltips in menus by default. This is because menu and menu items should have self-explaining names and if the menu names are good enough, the tooltips are redundant. You can get around this however by subclassing QMenu and reimplementing QMenu::event() http://doc.qt.io/qt-5 | Qt does not support tooltips in menus by default. This is because menu and menu items should have self-explaining names and if the menu names are good enough, the tooltips are redundant. You can get around this however by subclassing QMenu and reimplementing QMenu::event() http://doc.qt.io/qt-5/qmenu.html#event to intercept the QEvent::ToolTip http://doc.qt.io/qt-5/qevent.html#Type-enum event and call | ||
< | <syntaxhighlight lang="cpp">QToolTip::showText(helpEvent->globalPos(), activeAction()->toolTip());</syntaxhighlight> | ||
to set the tooltip for the active action. | to set the tooltip for the active action. | ||
Line 11,112: | Line 10,933: | ||
The following example illustrates how this can be done: | The following example illustrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Menu : public QMenu | class Menu : public QMenu | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
Menu() | |||
{} | |||
bool event (QEvent * e) | |||
{ | |||
const QHelpEvent *helpEvent = static_cast <QHelpEvent *>(e); | |||
if (helpEvent->type() == QEvent::ToolTip) { | |||
// call QToolTip::showText on that QAction's tooltip. | |||
QToolTip::showText(helpEvent->globalPos(), activeAction()->toolTip()); | |||
} else { | |||
QToolTip::hideText(); | |||
} | |||
return QMenu::event(e); | |||
} | |||
}; | }; | ||
class MainWindow : public QMainWindow | class MainWindow : public QMainWindow | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
MainWindow() | |||
{ | |||
Menu *menu = new Menu(); | |||
menu->setTitle(Test menu); | |||
menuBar()->addMenu(menu); | |||
QAction *action1 = menu->addAction(First); | |||
action1->setToolTip(First action); | |||
action1->setStatusTip(First action); | |||
QAction *action2 = menu->addAction(Second); | |||
action2->setToolTip(Second action); | |||
action2->setStatusTip(Second action); | |||
QAction *action3 = menu->addAction(Third); | |||
action3->setToolTip(Third action); | |||
action3->setStatusTip(Third action); | |||
setCentralWidget(new QTextEdit(this)); | |||
statusBar(); | |||
} | |||
}; | }; | ||
Line 11,160: | Line 10,981: | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
MainWindow window; | |||
window.show(); | |||
return app.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
Also, note that when a menu item is hovered, the QAction::statusTip() http://doc.qt.io/qt-5 | Also, note that when a menu item is hovered, the QAction::statusTip() http://doc.qt.io/qt-5/qaction.html#statusTip-prop text will be displayed in the status bar, if there is one. | ||
===How can I do file handling in QML?=== | ===How can I do file handling in QML?=== | ||
QML does not contain functionality for doing file handling. You can however implement this logic in C++ and expose it to QML as explained in detail in the Getting Started Programming with QML http://doc.qt.io/qt-5 | QML does not contain functionality for doing file handling. You can however implement this logic in C++ and expose it to QML as explained in detail in the Getting Started Programming with QML http://doc.qt.io/qt-5/gettingstartedqml.html tutorial. | ||
===How can I create a window that has no taskbar entry?=== | ===How can I create a window that has no taskbar entry?=== | ||
In order to create a window that has no taskbar entry, you can create a dummy widget that acts as a parent for a second widget and keep the dummy widget hidden. Then you can pass in the Window http://doc.qt.io/qt-5 | In order to create a window that has no taskbar entry, you can create a dummy widget that acts as a parent for a second widget and keep the dummy widget hidden. Then you can pass in the Window http://doc.qt.io/qt-5/qt.html#WindowType-enum flag to the second widget. The following example illustrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
QWidget w1; | |||
QWidget *w2 = new QWidget(&w1, Qt::Window); | |||
w2->resize(100,100); | |||
w2->show(); | |||
return app.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I use QML in a worker thread?=== | ===How can I use QML in a worker thread?=== | ||
The QML engine and the rendering can only run in the GUI thread. The QML WorkerScript http://doc.qt.io/qt-5 | The QML engine and the rendering can only run in the GUI thread. The QML WorkerScript http://doc.qt.io/qt-5/qml-workerscript.html however allows you to run operations in new threads. | ||
===How can I iterate over all the children in my window?=== | ===How can I iterate over all the children in my window?=== | ||
You can iterate over all the children in your window using QObject::findChildren() http://doc.qt.io/qt-5 | You can iterate over all the children in your window using QObject::findChildren() http://doc.qt.io/qt-5/qobject.html#findChildren. | ||
The example below illustrates how this can be done: | The example below illustrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class MainWindow : public QMainWindow | class MainWindow : public QMainWindow | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
MainWindow() | |||
{ | |||
QWidget *wid1 = new QWidget(this); | |||
wid1->setAutoFillBackground(true); | |||
setCentralWidget(wid1); | |||
QLineEdit *edit1 = new QLineEdit(wid1); | |||
QPushButton *button1 = new | |||
QPushButton(Click me to change color of all children, wid1); | |||
QHBoxLayout *layout = new QHBoxLayout(wid1); | |||
layout->addWidget(edit1); | |||
layout->addWidget(button1); | |||
QWidget *wid2 = new QWidget(wid1); | |||
layout->addWidget(wid2); | |||
QLineEdit *edit2 = new QLineEdit(wid2); | |||
QPushButton *button2 = new QPushButton(wid2); | |||
QVBoxLayout *layout2 = new QVBoxLayout(wid2); | |||
layout2->addWidget(edit2); | |||
layout2->addWidget(button2); | |||
connect(button1, SIGNAL(clicked()), this, SLOT(changeChildrenColor())); | |||
} | |||
public slots: | |||
void changeChildrenColor() | |||
{ | |||
qApp->setStyle(new QWindowsStyle()); | |||
QList<QWidget*> list = findChildren<QWidget *>(); | |||
QPalette pal = palette(); | |||
pal.setColor(QPalette::Window, Qt::red); | |||
pal.setColor(QPalette::Base, Qt::blue); | |||
pal.setColor(QPalette::Button, Qt::green); | |||
foreach(QWidget *w, list) { | |||
w->setPalette(pal); | |||
} | |||
} | |||
}; | }; | ||
Line 11,251: | Line 11,072: | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
MainWindow window; | |||
window.show(); | |||
return app.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
===How to change the application title in the application menu on the Mac from being the application name?=== | ===How to change the application title in the application menu on the Mac from being the application name?=== | ||
On the Mac the application title is displayed in the application menu and will by default be the name of the application. In order to change the name of the application title, you need to modify the Info.plist file which is part of your application. The easiest way to do this would be to copy the existing one from your application at: | On the Mac the application title is displayed in the application menu and will by default be the name of the application. In order to change the name of the application title, you need to modify the Info.plist file which is part of your application. The easiest way to do this would be to copy the existing one from your application at: | ||
< | <syntaxhighlight lang="cpp">application.app/Contents/Info.plist | ||
</ | </syntaxhighlight> | ||
and put it in your source directory. Then modify that file and add the lines: | and put it in your source directory. Then modify that file and add the lines: | ||
< | <syntaxhighlight lang="cpp"><key>CFBundleName</key> | ||
<string>Application Name Goes Here</string> | <string>Application Name Goes Here</string> | ||
</ | </syntaxhighlight> | ||
then add the following line to your pro file: | then add the following line to your pro file: | ||
< | <syntaxhighlight lang="cpp">QMAKE_INFO_PLIST = Info.plist | ||
</ | </syntaxhighlight> | ||
After removing the existing application.app do: | After removing the existing application.app do: | ||
Line 11,280: | Line 11,101: | ||
and this should change the name of the application title for you. | and this should change the name of the application title for you. | ||
===How can I export the contents of a QTableWidget to an excel workbook?=== | ===How can I export the contents of a QTableWidget to an excel workbook?=== | ||
You can use ActiveQt http://doc.qt.io/qt-5 | You can use ActiveQt http://doc.qt.io/qt-5/qt-activex.html in order to export the contents of a QTableWidget http://doc.qt.io/qt-5/qtablewidget.html to an excel workbook. The bulk of the work is done via the Excel functions made available to the ActiveX control. | ||
The following example shows a basic implementation on how to do this. | The following example shows a basic implementation on how to do this. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
QApplication a(argc, argv); | QApplication a(argc, argv); | ||
QAxObject *mExcelApp = new QAxObject(Excel.Application); // Start Excel | QAxObject *mExcelApp = new QAxObject(Excel.Application); // Start Excel | ||
Line 11,307: | Line 11,128: | ||
} | } | ||
tw.show(); | tw.show(); | ||
for (int i = 0; i < | for (int i = 0; i < tw.rowCount(); i++) { | ||
QVariantList vListOfValues; | QVariantList vListOfValues; | ||
for (int j = 0; j < tw.columnCount(); j++) { | for (int j = 0; j < tw.columnCount(); j++) { | ||
Line 11,319: | Line 11,140: | ||
return a.exec(); | return a.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I embed widgets in QML?=== | ===How can I embed widgets in QML?=== | ||
You can embed QWidget-based objects into QML using QGraphicsProxyWidget http://doc.qt.io/qt-5 | You can embed QWidget-based objects into QML using QGraphicsProxyWidget http://doc.qt.io/qt-5/qgraphicsproxywidget.html. There is an example showing how to do it here http://doc.qt.io/qt-5/declarative-cppextensions-qwidgets.html. | ||
===How can I resize the QMainWindow to the size of its central widget after removing the QDockWidgets?=== | ===How can I resize the QMainWindow to the size of its central widget after removing the QDockWidgets?=== | ||
In order to resize the QMainWindow http://doc.qt.io/qt-5 | In order to resize the QMainWindow http://doc.qt.io/qt-5/qmainwindow.html to the size of its central widget after removing the QDockWidgets http://doc.qt.io/qt-5/qdockwidget.html, you need to call QLayout::activate() http://doc.qt.io/qt-5/qlayout.html#activate on the layout to inform the QMainWindow that the layout has changed. | ||
The following example illustrates how this can be done: | The following example illustrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class MainWindow : public QMainWindow | class MainWindow : public QMainWindow | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
MainWindow() | |||
{ | |||
setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); | |||
dock1 = new QDockWidget(this); | |||
QPushButton *button = new QPushButton(Click me, this); | |||
button->setCheckable(true); | |||
setCentralWidget(button); | |||
button->setMaximumHeight(24); | |||
addDockWidget(Qt::BottomDockWidgetArea, dock1); | |||
connect(button, SIGNAL(toggled(bool)), this, SLOT(toggleDockWidget(bool))); | |||
} | |||
QSize sizeHint() const | |||
{ | |||
return QSize(800, 24); | |||
} | |||
QSize minimumSizeHint() const | |||
{ | |||
return QSize(800, 24); | |||
} | |||
public slots: | |||
void toggleDockWidget(bool test) | |||
{ | |||
if (test) { | |||
removeDockWidget(dock1); | |||
layout()->activate(); | |||
resize(sizeHint()); | |||
} else { | |||
restoreDockWidget(dock1); | |||
} test = !test; | |||
} | |||
private: | private: | ||
QToolBar *toolBar; | |||
QDockWidget *dock1; | |||
}; | }; | ||
Line 11,381: | Line 11,202: | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
MainWindow window; | |||
window.resize(window.sizeHint()); | |||
window.show(); | |||
return app.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I modify the context menu that lists dockwidgets and toolbars in QMainWindow?=== | ===How can I modify the context menu that lists dockwidgets and toolbars in QMainWindow?=== | ||
In order to modify the context menu that lists dockwidgets and toolbars in QMainWindow http://doc.qt.io/qt-5 | In order to modify the context menu that lists dockwidgets and toolbars in QMainWindow http://doc.qt.io/qt-5/qmainwindow.html, you can reimplement QMainWindow::createPopupMenu() http://doc.qt.io/qt-5/qmainwindow.html#createPopupMenu and return a new QMenu http://doc.qt.io/qt-5/qmenu.html with the actions you would like. Alternatively, if you only want to add to the existing menu, you can get hold of that one by calling the base class implementation and add any action you want to it. | ||
The example below illustrates how you can reimplement QMainWindow::createPopupMenu() and add an action to the existing menu. | The example below illustrates how you can reimplement QMainWindow::createPopupMenu() and add an action to the existing menu. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class MainWindow : public QMainWindow | class MainWindow : public QMainWindow | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
MainWindow() | |||
{ | |||
QDockWidget *dock1 = new QDockWidget(this); | |||
dock1->setWindowTitle(Dock 1); | |||
dock1->setWidget(new QTextEdit(dock1)); | |||
QToolBar *tool = new QToolBar(this); | |||
tool->setWindowTitle(Tool); | |||
tool->addAction(Test action); | |||
addDockWidget(Qt::TopDockWidgetArea, dock1); | |||
addToolBar(tool); | |||
setCentralWidget(new QTextEdit(this)); | |||
}; | |||
QMenu* createPopupMenu () | |||
{ | |||
QMenu *menu = QMainWindow::createPopupMenu(); | |||
menu->addAction(An added action); | |||
return menu; | |||
} | |||
}; | }; | ||
Line 11,427: | Line 11,248: | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
MainWindow window; | |||
window.show(); | |||
return app.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I create new QObjects in QML?=== | ===How can I create new QObjects in QML?=== | ||
In order to create new QObjects http://doc.qt.io/qt-5 | In order to create new QObjects http://doc.qt.io/qt-5/qobject.html in QML, you can subclass QDeclarativeItem http://doc.qt.io/qt-5/qdeclarativeitem.html and implement your own painting and functionality like for any other QGraphicsObject http://doc.qt.io/qt-5/qgraphicsobject.html. Note that QGraphicsItem::ItemHasNoContents http://doc.qt.io/qt-5/qgraphicsitem.html#GraphicsItemFlag-enum is set by default on QDeclarativeItem because it does not paint anything; so you will need to clear this if your item is supposed to paint anything (as opposed to being solely for input handling or logical grouping). If the item is not going to be visible, you can inherit from QObject directly instead of from QDeclarativeItem. | ||
In order for QML to be able to create and manipulate this object, you need to register it with the QML engine using qmlRegisterType() http://doc.qt.io/qt-5 | In order for QML to be able to create and manipulate this object, you need to register it with the QML engine using qmlRegisterType() http://doc.qt.io/qt-5/qdeclarativeengine.html#qmlRegisterType. | ||
The example below illustrates how this can be done. | The example below illustrates how this can be done. | ||
main.cpp | main.cpp | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
#include <QtDeclarative> | #include <QtDeclarative> | ||
class Circle: public QDeclarativeItem | class Circle: public QDeclarativeItem | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
Circle() | |||
{ | |||
setFlag(QGraphicsItem::ItemHasNoContents, false); | |||
} | |||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override | |||
{ | |||
painter->drawEllipse(QRect(10, 20, 80, 60)); | |||
} | |||
}; | }; | ||
Line 11,465: | Line 11,286: | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
qmlRegisterType<Circle>(MyCircle, 1, 0, Circle); | |||
QDeclarativeView view; | |||
view.setSource(QUrl::fromLocalFile(test.qml)); | |||
view.resize(200, 200); | |||
view.show(); | |||
return app.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
test.qml | test.qml | ||
< | <syntaxhighlight lang="cpp"> | ||
import MyCircle 1.0 | import MyCircle 1.0 | ||
import QtQuick 1.0 | import QtQuick 1.0 | ||
Item { | Item { | ||
width: 100; height: 100 | width: 100; height: 100 | ||
Circle { | Circle { | ||
id: ellipse | |||
anchors.centerIn: parent | |||
} | } | ||
} | } | ||
</ | </syntaxhighlight> | ||
The Defining New QML elements documentation http://doc.qt.io/qt-5 | The Defining New QML elements documentation http://doc.qt.io/qt-5/qtbinding.html#defining-new-qml-elements contains more information on this and so does this tutorial http://doc.qt.io/qt-5/declarative-tutorials-extending-chapter1-basics.html. | ||
===How can I add elements created in QML to a QGraphicsView ?=== | ===How can I add elements created in QML to a QGraphicsView ?=== | ||
In order to add elements created in QML to a QGraphicsView http://doc.qt.io/qt-5 | In order to add elements created in QML to a QGraphicsView http://doc.qt.io/qt-5/qgraphicsview.html, you can create a QDeclarativeComponent http://doc.qt.io/qt-5/qdeclarativecomponent.html which loads the QML code and then create an instance of this component using create() http://doc.qt.io/qt-5/qdeclarativecomponent.html#create. For example: | ||
< | <syntaxhighlight lang="cpp">QDeclarativeEngine engine; | ||
QDeclarativeComponent component(&engine); | QDeclarativeComponent component(&engine); | ||
component.setData(import QtQuick 1.0\nText { text: \Hello world!\ }, QUrl()); | component.setData(import QtQuick 1.0\nText { text: \Hello world!\ }, QUrl()); | ||
QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(component.create()); | QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(component.create()); | ||
</ | </syntaxhighlight> | ||
Since QDeclarativeItem http://doc.qt.io/qt-5 | Since QDeclarativeItem http://doc.qt.io/qt-5/qdeclarativeitem.html is a QGraphicsObject http://doc.qt.io/qt-5/qgraphicsobject.html you can add it to your QGraphicsScene http://doc.qt.io/qt-5/qgraphicsscene.html. | ||
The following example illustrates how this can be done. | The following example illustrates how this can be done. | ||
main.cpp | main.cpp | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
#include <QtDeclarative> | #include <QtDeclarative> | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
QDeclarativeEngine engine; | |||
QDeclarativeComponent component(&engine); | |||
component.loadUrl(QUrl::fromLocalFile(test.qml)); | |||
QDeclarativeItem *item = qobject_cast <QDeclarativeItem *>(component.create()); | |||
QGraphicsView view; | |||
QGraphicsScene *scene = new QGraphicsScene(&view); | |||
view.setScene(scene); | |||
scene->addItem(item); | |||
view.show(); | |||
return app.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
test.qml | test.qml | ||
< | <syntaxhighlight lang="cpp"> | ||
import QtQuick 1.0 | import QtQuick 1.0 | ||
Line 11,540: | Line 11,361: | ||
radius: 10 | radius: 10 | ||
} | } | ||
</ | </syntaxhighlight> | ||
Line 11,546: | Line 11,367: | ||
===Is there any way to include a .qrc file in another .qrc file?=== | ===Is there any way to include a .qrc file in another .qrc file?=== | ||
It is not possible to include a .qrc file in another .qrc file. Instead, you can use .pri files to get around this. Those .pri files can then reference one or more resource files and/or include other .pri files. In your .pro file, you then include() http://doc.qt.io/qt-5 | It is not possible to include a .qrc file in another .qrc file. Instead, you can use .pri files to get around this. Those .pri files can then reference one or more resource files and/or include other .pri files. In your .pro file, you then include() http://doc.qt.io/qt-5/qmake-function-reference.html#include-filename the .pri file you want, and all the resources in the tree of resource .pri files will be added to your project. | ||
===How can I pass a value or a string from QML to C++?=== | ===How can I pass a value or a string from QML to C++?=== | ||
In order to pass a value or a string from QML to C++, you can create a function that is callable from QML by marking it with Q_INVOKABLE http://doc.qt.io/qt-5 | In order to pass a value or a string from QML to C++, you can create a function that is callable from QML by marking it with Q_INVOKABLE http://doc.qt.io/qt-5/qobject.html#Q_INVOKABLE as documented here http://doc.qt.io/qt-5/qml-extending.html#methods. Slots are callable from QML without the need for the Q_INVOKABLE macro. Then you can make the class containing the function or slot accessible in QML by calling QDeclarativeView::rootObject() http://doc.qt.io/qt-5/qdeclarativeview.html#rootContext and simply call the function or the slot with the appropriate value from QML and it will be handled on the C++ side . | ||
The following example illustrates how this can be done. | The following example illustrates how this can be done. | ||
main.cpp | main.cpp | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
#include <QtDeclarative> | #include <QtDeclarative> | ||
Line 11,562: | Line 11,383: | ||
public: | public: | ||
Q_INVOKABLE void cppMethod(const QString &msg) | Q_INVOKABLE void cppMethod(const QString &msg) | ||
{ | |||
qDebug() << Called the C++ method with << msg; | qDebug() << Called the C++ method with << msg; | ||
} | } | ||
public slots: | public slots: | ||
void cppSlot(int number) { | void cppSlot(int number) { | ||
Line 11,573: | Line 11,394: | ||
#include main.moc" | #include main.moc" | ||
int main(int argc, char *argv[]) { | int main(int argc, char *argv[]) { | ||
QApplication app(argc, argv); | QApplication app(argc, argv); | ||
QDeclarativeView view; | QDeclarativeView view; | ||
MyObject MyObject; | MyObject MyObject; | ||
view.rootContext()->setContextProperty(myObject, &MyObject); | view.rootContext()->setContextProperty(myObject, &MyObject); | ||
view.setSource(QUrl::fromLocalFile(main.qml)); | view.setSource(QUrl::fromLocalFile(main.qml)); | ||
view.resize(200,200); | |||
view.show(); | view.show(); | ||
return app.exec(); | return app.exec(); | ||
} | } | ||
</ | </syntaxhighlight> | ||
main.qml | main.qml | ||
< | <syntaxhighlight lang="cpp"> | ||
import QtQuick 1.0 | import QtQuick 1.0 | ||
Line 11,596: | Line 11,417: | ||
width: 100; height: 100 | width: 100; height: 100 | ||
color: blue" | color: blue" | ||
MouseArea { | MouseArea { | ||
anchors.fill: parent | |||
onClicked: { | |||
myObject.cppMethod(Hello from QML) | myObject.cppMethod(Hello from QML) | ||
myObject.cppSlot(37) | myObject.cppSlot(37) | ||
Line 11,606: | Line 11,427: | ||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I create multiple toplevel windows in QML?=== | ===How can I create multiple toplevel windows in QML?=== | ||
Currently Qt does not provide support for creating toplevel windows directly inside a QML application. To create multiple windows, you��l have to create multiple toplevel QDeclarativeViews (or another widget). However, you can check out the following project http://blog.qt.io/2011/08/26/toplevel-windows-and-menus-with-qt-quick/ on Qt Labs which provides functionality for creating toplevel windows directly in QML. | Currently Qt does not provide support for creating toplevel windows directly inside a QML application. To create multiple windows, you��l have to create multiple toplevel QDeclarativeViews (or another widget). However, you can check out the following project http://blog.qt.io/2011/08/26/toplevel-windows-and-menus-with-qt-quick/ on Qt Labs which provides functionality for creating toplevel windows directly in QML. | ||
Line 11,615: | Line 11,436: | ||
main.cpp | main.cpp | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
#include <QtDeclarative> | #include <QtDeclarative> | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
QDeclarativeView view; | |||
view.setSource(QUrl::fromLocalFile(main.qml)); | |||
view.resize(800,200); | |||
view.show(); | |||
return app.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
main.qml | main.qml | ||
< | <syntaxhighlight lang="cpp"> | ||
import QtQuick 1.0 | import QtQuick 1.0 | ||
Rectangle { | Rectangle { | ||
width: 740; height: 150 | width: 740; height: 150 | ||
Column { | Column { | ||
anchors.fill: parent; spacing: 20 | anchors.fill: parent; spacing: 20 | ||
Text { | Text { | ||
text: Example that illustrates how to allow external objects to directly modify and access child objects in a component" | text: Example that illustrates how to allow external objects to directly modify and access child objects in a component" | ||
font.pointSize: 12; anchors.horizontalCenter: parent.horizontalCenter | font.pointSize: 12; anchors.horizontalCenter: parent.horizontalCenter | ||
} | |||
} | } | ||
Row { | Row { | ||
anchors.verticalCenter: parent.verticalCenter | |||
Button { onClicked: { buttonLabel = New value for Button } } | Button { onClicked: { buttonLabel = New value for Button } } | ||
Button { onClicked: { buttonLabel = New value for Button }} | |||
Button { onClicked: { buttonLabel = New value for Button }} | |||
} | } | ||
} | } | ||
</ | </syntaxhighlight> | ||
Button.qml | Button.qml | ||
< | <syntaxhighlight lang="cpp"> | ||
import QtQuick 1.0 | import QtQuick 1.0 | ||
Line 11,662: | Line 11,483: | ||
id: root; | id: root; | ||
property alias buttonLabel: label.text | property alias buttonLabel: label.text | ||
signal clicked() | signal clicked() | ||
width: 120 | width: 120 | ||
height: 30 | height: 30 | ||
color: mouse.pressed ? lightgray : white" | color: mouse.pressed ? lightgray : white" | ||
radius: 4 | radius: 4 | ||
border.width: 1 | border.width: 1 | ||
border.color: gray" | border.color: gray" | ||
MouseArea { | MouseArea { | ||
id: mouse | |||
anchors.fill: parent | |||
onClicked: root.clicked(); | |||
} | } | ||
Text { | Text { | ||
id: label | |||
anchors.centerIn: parent | |||
text: Click Me" | |||
} | } | ||
} | } | ||
</ | </syntaxhighlight> | ||
===Why do I get metatype errors when trying to use my custom class with QVariant and properties?=== | ===Why do I get metatype errors when trying to use my custom class with QVariant and properties?=== | ||
In order to use a custom type in QVariant http://doc.qt.io/qt-5 | In order to use a custom type in QVariant http://doc.qt.io/qt-5/qvariant.html it is necessary to make the custom type known to QMetaType http://doc.qt.io/qt-5/qmetatype.html using Q_DECLARE_METATYPE http://doc.qt.io/qt-5/qmetatype.html#Q_DECLARE_METATYPE. If this is not done, you will get metatype errors similar to the following: | ||
< | <syntaxhighlight lang="cpp"> | ||
error C2039: 'qt_metatype_id' : is not a member of 'QMetaTypeId<T>' | error C2039: 'qt_metatype_id' : is not a member of 'QMetaTypeId<T>' | ||
with | with | ||
Line 11,695: | Line 11,516: | ||
T=MyValue | T=MyValue | ||
] | ] | ||
</ | </syntaxhighlight> | ||
If you also need to use the custom type with QObject::property() http://doc.qt.io/qt-5 | If you also need to use the custom type with QObject::property() http://doc.qt.io/qt-5/qobject.html#property or in queued connections you need to register the type using qRegisterMetaType() http://doc.qt.io/qt-5/qmetatype.html#qRegisterMetaType as well. Otherwise, you will run into errors like the following: | ||
< | <syntaxhighlight lang="cpp">QMetaProperty::read: Unable to handle unregistered datatype 'MyValue' for property 'QTestObj::Test'</syntaxhighlight> | ||
The example below shows how this can be implemented. | The example below shows how this can be implemented. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class MyValue | class MyValue | ||
{ | { | ||
public: | public: | ||
MyValue(double number) | |||
{ | |||
number1 = number; | |||
} | |||
MyValue() | |||
{} | |||
double toDouble() { return number1; } | |||
private: | private: | ||
double number1; | |||
}; | }; | ||
Line 11,724: | Line 11,545: | ||
class QTestObj : public QObject | class QTestObj : public QObject | ||
{ | { | ||
Q_OBJECT | |||
Q_PROPERTY(MyValue Test READ getTest WRITE setTest) | |||
public: | public: | ||
QTestObj(QObject* parent = nullptr) : QObject(parent) , test(5.0) | |||
{} | |||
MyValue getTest() const { return test; } | |||
void setTest(MyValue newValue) { test = newValue; } | |||
private: | private: | ||
MyValue test; | |||
}; | }; | ||
Line 11,742: | Line 11,563: | ||
int main(int argc, char *argv[]) | int main(int argc, char *argv[]) | ||
{ | { | ||
QTestObj Test; | |||
qRegisterMetaType<MyValue>(MyValue); | |||
qDebug() << Value of property 'Test' is equal << Test.property(Test).value<MyValue>().toDouble(); | |||
qDebug() << Trying set new value for property 'Test'...; | |||
if (Test.setProperty(Test, QVariant::fromValue<MyValue>(0.25))) | |||
{ | |||
qDebug() << New value is set successfully.; | |||
} else { | |||
qDebug() << Method setPropery failed!; | |||
} | |||
qDebug() << Test.property(Test).value<MyValue>().toDouble(); | |||
return 0; | |||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I change the column width of a QTableWidget when it is being resized?=== | ===How can I change the column width of a QTableWidget when it is being resized?=== | ||
You can set the headers ResizeMode http://doc.qt.io/qt-5 | You can set the headers ResizeMode http://doc.qt.io/qt-5/qheaderview.html#ResizeMode-enum to be QHeaderView::Stretch, then the columns and rows will resize when you resize the widget. | ||
The following example illustrates how this can be done. | The following example illustrates how this can be done. | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class TableWidget : public QTableWidget | class TableWidget : public QTableWidget | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
TableWidget() | |||
{ | |||
setRowCount(10); | |||
setColumnCount(5); | |||
QTableWidgetItem *newItem = new QTableWidgetItem(An item); | |||
setItem(0,0, newItem); | |||
horizontalHeader()->setResizeMode(QHeaderView::Stretch); | |||
verticalHeader()->setResizeMode(QHeaderView::Stretch); | |||
} | |||
}; | }; | ||
Line 11,785: | Line 11,606: | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
TableWidget window; | |||
window.resize(400,400); | |||
window.show(); | |||
return app.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I make a window unmovable?=== | ===How can I make a window unmovable?=== | ||
It is the window manager that controls the moving of the window through the titlebar and Qt has no influence over that unfortunately. You can use one of the following approaches to prevent the window from being moved though: | It is the window manager that controls the moving of the window through the titlebar and Qt has no influence over that unfortunately. You can use one of the following approaches to prevent the window from being moved though: | ||
Line 11,800: | Line 11,621: | ||
===How can I remove the plus/minus sign from a QTreeWidget and still be able to expand the items?=== | ===How can I remove the plus/minus sign from a QTreeWidget and still be able to expand the items?=== | ||
You can modify the drawing of the branches in the style to not draw the minus/plus sign. Reimplement drawPrimitive() http://doc.qt.io/qt-5 | You can modify the drawing of the branches in the style to not draw the minus/plus sign. Reimplement drawPrimitive() http://doc.qt.io/qt-5/qstyle.html#drawPrimitive and remove the QStyle::State_Children http://doc.qt.io/qt-5/qstyle.html#StateFlag-enum state from the QStyleOption http://doc.qt.io/qt-5/qstyleoption.html and the minus/plus sign will be gone. | ||
The example below illustrates how this can be done: | The example below illustrates how this can be done: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
class Style : public QWindowsStyle | class Style : public QWindowsStyle | ||
{ | { | ||
public: | public: | ||
Style() | |||
{} | |||
void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w) const | |||
{ | |||
QStyleOption* op = const_cast<QStyleOption*>(opt); | |||
op->state &= ~ QStyle::State_Children; | |||
QWindowsStyle::drawPrimitive(pe, op, p, w); | |||
} | |||
}; | }; | ||
class TreeWidget : public QTreeWidget | class TreeWidget : public QTreeWidget | ||
{ | { | ||
Q_OBJECT | |||
public: | public: | ||
TreeWidget() | |||
{ | |||
QTreeWidgetItem *root = invisibleRootItem(); | |||
QTreeWidgetItem *firstItem = new QTreeWidgetItem(root); | |||
firstItem->setText(0,First); | |||
QTreeWidgetItem *secondItem = new QTreeWidgetItem(firstItem); | |||
secondItem->setText(0,Second); | |||
QTreeWidgetItem *thirdItem = new QTreeWidgetItem(secondItem); | |||
thirdItem->setText(0,Third); | |||
} | |||
}; | }; | ||
Line 11,837: | Line 11,658: | ||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||
{ | { | ||
QApplication app(argc, argv); | |||
TreeWidget tree; | |||
tree.setStyle(new Style()); | |||
tree.show(); | |||
return app.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
===How can I move entire rows in my QTableWidget?=== | ===How can I move entire rows in my QTableWidget?=== | ||
You can move entire rows in a QTableWidget http://doc.qt.io/qt-5 | You can move entire rows in a QTableWidget http://doc.qt.io/qt-5/qtablewidget.html by calling setMovable() http://doc.qt.io/qt-5/qheaderview.html#setMovable on the vertical header. | ||
See the following example for an illustration: | See the following example for an illustration: | ||
< | <syntaxhighlight lang="cpp"> | ||
#include < | #include <QtWidgets> | ||
int main( int argc, char** argv ) | int main( int argc, char** argv ) | ||
{ | { | ||
QApplication a( argc, argv ); | |||
QTableWidget table(4,4); | |||
for (int row = 0; row < 4; row++) { | |||
for(int col = 0; col < 4; col++) { | |||
QTableWidgetItem *item = new QTableWidgetItem(QString(Row%1 Col%2).arg(row).arg(col)); | |||
item->setFlags(item->flags() | Qt::ItemIsSelectable); | |||
table.setItem(row,col,item); | |||
} | |||
} | |||
table.verticalHeader()->setMovable(true); | |||
table.show(); | |||
return a.exec(); | |||
} | } | ||
</ | </syntaxhighlight> | ||
Latest revision as of 10:59, 2 May 2022
En Ar Bg De El Es Fa Fi Fr Hi Hu It Ja Kn Ko Ms Nl Pl Pt Ru Sq Th Tr Uk Zh
This page contains technical FAQs. The FAQs have accumulated over a long time period and some of the content may not apply to the latest releases. Please be aware of this when you apply them to the latest builds of Qt.
When to use QPluginLoader vs QLibrary when splitting code into several dlls?
QPluginLoader http://doc.qt.io/qt-5/qpluginloader.html offers an advantage over QLibrary http://doc.qt.io/qt-5/qlibrary.html because it checks that the plugin is linked against the same version of Qt as the application. QLibrary will not do this check for you. If the library is Qt based and only used within a Qt application then this is probably the best approach. See the documentation http://doc.qt.io/qt-5/plugins-howto.html on how to create plugins.
If you want to make the dlls usable with other applications, then you will need to use QLibrary and create the library as a normal C++ library.
The plugin approach is generally the easier one to set up and use as you can drop in more plugins into the application without too much of a problem.
Finally, in order to break up your code into several dll's, you could simply create shared libraries that you link against, see:
http://doc.qt.io/qt-5/sharedlibrary.html
What is the process for contributing to Qt?
The contribution guidelines are detailed on this wiki page(Contribution guidelines) http://wiki.qt.io/Qt-Contribution-Guidelines
(Answer updated May 2014)
How can I invoke functions on QObjects from another thread?
There are a two basic methods for calling a function from one thread on a QObject in another thread.
- The most basic operation is to post an event to the object in the other thread. The event loop in the target objects thread will then deliver the event to the target object. See the documentation http://doc.qt.io/qt-5/threads-qobject.html#per-thread-event-loop.
- The second approach is to make use of Qt's queued connections. This is also implemented in terms of the first method, and works for any target object that has an event loop running in the thread that owns it. One can either specify a queued connection by passing the parameter Qt::QueuedConnection http://doc.qt.io/qt-5/qt.html#ConnectionType-enum to the connect statement or use Qt::AutoConnection, the default, which decides at runtime how the slot should be called. See the documentation http://doc.qt.io/qt-5/threads-qobject.html#signals-and-slots-across-threads
How can I rotate items in a QGraphicsView using the mouse?
You can rotate items in a QGraphicsView http://doc.qt.io/qt-5/qgraphicsview.html using the mouse by reimplementing the mousePressEvent() http://doc.qt.io/qt-5/qgraphicsitem.html#mousePressEvent and mouseMoveEvent() http://doc.qt.io/qt-5/qgraphicsitem.html#mouseMoveEvent for the items. In the mousePressEvent() you can store the position for the mouse press and use that in the mouseMoveEvent() in order to calculate the value for the rotation. The rotation can then be set in the mouseMoveEvent() either by creating a QTransform http://doc.qt.io/qt-5/qtransform.html and calling setTransform() http://doc.qt.io/qt-5/qgraphicsitem.html#setTransform on the item or by calling setRotation() http://doc.qt.io/qt-5/qgraphicsitem.html#setRotation on the item.
The example below illustrates how this can be done:
#include <QtWidgets>
class GraphicsEllipseItem : public QGraphicsEllipseItem
{
public:
GraphicsEllipseItem()
{
rotation = 0;
setFlags(flags() | QGraphicsItem::ItemIsSelectable);
}
void mousePressEvent(QGraphicsSceneMouseEvent *event)
{
initialPos = mapToScene(event->pos());
QGraphicsItem::mousePressEvent(event);
}
void mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
QPointF pos = mapToScene(event->pos());
if (pos.y() > initialPos.y()) {
++rotation;
} else {
--rotation;
}
#if 1
QTransform xform;
xform.rotate(rotation);
setTransform(xform);
#else
setRotation(rotation);
#endif
initialPos = pos;
}
QPointF initialPos;
qreal rotation;
};
class GraphicsView : public QGraphicsView
{
public:
GraphicsView()
{
QGraphicsScene *scene = new QGraphicsScene();
setScene(scene);
QRect rectangle(10, 20, 80, 60);
QRect rectangle2(50, 80, 80, 60);
GraphicsEllipseItem *item1 = new GraphicsEllipseItem();
item1->setRect(-40, -30, 80, 60);
scene->addItem(item1);
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
GraphicsView box;
box.show();
return app.exec();
}
The Makefile generated by the Qt Eclipse Integration has no 'dist' target. Is it really missing?
You find dist targets in both the generated Makefile.Debug and Makefile.Release. You can create an Eclipse Make Target with target 'dist' and build command 'make -f Makefile.Release' to use it from Eclipse.
Why is Qt released under LGPL?
The LGPL license will make it easier for developers to adopt Qt. By spreading the use of Qt as widely as possible and establishing a robust ecosystem.
How can I make the non-slot and non-property members of an object available to the script engine?
By default only a QObject's http://doc.qt.io/qt-5/qobject.html signals, slots, properties, and child objects are available to scripts when a QObject is passed to the QScriptEngine's newQObject() http://doc.qt.io/qt-5/qscriptengine.html#newQObject function.
In order to make other members of the class available to the engine you can use one of the following approaches:
- Create a binding for it yourself, for example by creating your own object that calls the relevant function in a slot.
- Use newFunction() http://doc.qt.io/qt-5/qscriptengine.html#newFunction
- Use the Qt Script Generator http://labs.trolltech.com/blogs/2008/03/10/bind-aid/ that generates Qt bindings for Qt Script, see:
How can I trigger the parent widget to resize when its child widget is resized programmatically?
It is the job of the layout to determine the size and position of the widgets. So if you explicitly resize a child widget which is inside a layout, you need to ensure that the new size is passed correctly through the layout system. This can be done by ensuring that the widget's sizeHint() http://doc.qt.io/qt-5/qwidget.html#sizeHint-prop returns the new size. The value returned by the sizeHint() will be used when the layout calculates the new size. So after the sizeHint() has changed, simply call updateGeometry() http://doc.qt.io/qt-5/qwidget.html#updateGeometry that will notify the layout system that the widget has changed and may need to change geometry.
An alternative way to ensure that the parent widget is resized in response to its child being resized, is to call setFixedSize() http://doc.qt.io/qt-5/qwidget.html#setFixedSize on the child.
The following example illustrates how this can be done:
#include <QtWidgets>
class Label : public QLabel
{
Q_OBJECT
public:
Label(const QString &text, QWidget *parent) : QLabel(text, parent)
{
changeSize = false;
setAutoFillBackground(true);
QPalette pal = palette();
pal.setColor(QPalette::Window, Qt::red);
setPalette(pal);
}
QSize sizeHint() const
{
if(changeSize) {
return QSize(400, 400);
} else {
return QLabel::sizeHint();
}
}
void setChangedSize(bool value)
{
changeSize = value;
}
private:
bool changeSize;
};
class Widget : public QWidget
{
Q_OBJECT
public:
Widget()
{
label = new Label("Hello World", this);
QLabel *label2 = new QLabel("Standard label", this);
label2->setAutoFillBackground(true);
QPalette pal = label2->palette();
pal.setColor(QPalette::Window, Qt::blue);
label2->setPalette(pal);
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(label);
layout->addWidget(label2);
QTimer::singleShot(2000, this, SLOT(testSlot()));
}
public slots:
void testSlot()
{
#if 0
label->setFixedSize(400,400);
#else
QSize oldSize = label->size();
label->setChangedSize(true);
if(oldSize.width() < label->sizeHint().width() ||
oldSize.height() < label->sizeHint().height()) {
label->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
label->updateGeometry();
} else {
label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
label->updateGeometry();
}
#endif
}
private:
Label *label;
};
#include "main.moc"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
Widget widget;
widget.resize(200,200);
widget.show();
return app.exec();
}
Assistant does not launch or the documentation does not show up when launching Assistant, what is wrong?
Deleting the following Qt Assistant http://doc.qt.io/qt-5/assistant-manual.html key in the registry might solve the problem:
- HKEY_CURRENT_USER\SOFTWARE\Trolltech\Qt Assistant*
When I set a font/palette explicitly for a QLabel on the Mac, then it is respected. If my QLabel only inherits the font, then it is ignored. What is the reason for this?
This is the expected behavior. Qt/Mac tries to set widget specific fonts and palettes for certain widgets at startup and also when the application gains focus. Unless you specify the font or palette explicitly yourself for a widget then the system font will override your font settings. You can avoid this behavior by calling setDesktopSettingsAware() http://doc.qt.io/qt-5/qapplication.html#setDesktopSettingsAware with false as an argument first in your application.
When in doubt, set the font or palette directly.
You can remove actions from the menubar using QWidget::removeAction() http://doc.qt.io/qt-5/qwidget.html#removeAction.
In order to get hold of the action associated with the menu, use QMenu::menuAction() http://doc.qt.io/qt-5/qmenu.html#menuAction
The example below demonstrates how this can be done:
#include <QtWidgets>
class MainWindow : public QMainWindow
{
public:
MainWindow()
{
QMenu *menu = menuBar()->addMenu("Test");
QMenu *menu2 = menuBar()->addMenu("Test2");
menu->addAction("First");
menu2->addAction("Second");
menuBar()->removeAction(menu->menuAction());
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
MainWindow box;
box.show();
return app.exec();
}
How can I get/set the max length of a QTextEdit ?
There is no direct API to set/get a maximum length of a QTextEdit, but you can handle this yourself by connecting a slot to the contentsChanged() http://doc.qt.io/qt-5/qtextdocument.html#contentsChanged signal and then call toPlainText().length() http://doc.qt.io/qt-5/qtextdocument.html#toPlainText to find out how big it is. If it is up to the limit then you can reimplement keyPressEvent() http://doc.qt.io/qt-5/qtextedit.html#keyPressEvent and keyReleaseEvent() http://doc.qt.io/qt-5/qtextedit.html#keyReleaseEvent to do nothing for normal characters.
Lines with width 1 disappear when not using anti-aliasing
When having a transformation set and not using anti-aliasing then if you draw something that's smaller than a pixel, you are not guaranteed that it will get drawn. In order to guarantee that it shows up you need to either turn on anti-aliasing or draw using a cosmetic pen.
Should one use qApp or QCoreApplication::instance() when referring to the application object?
It does not matter which one you use. The instance() http://doc.qt.io/qt-5/qcoreapplication.html#instance function was added since many feel using a function and not a global variable is more elegant, qApp http://doc.qt.io/qt-5/qapplication.html#qApp is kept for compatibility reasons and for those who prefer global pointers
When keeping a key pressed down, then I receive a number of keyReleaseEvents() in addition to keyPressEvents(). Why is this happening and what can be done to only get a mousePressEvent() ?
When a given key is continuously pressed it results in a continuous stream of events for the associated key. You will get both keyPressEvents() http://doc.qt.io/qt-5/qwidget.html#keyPressEvent and keyReleaseEvents() http://doc.qt.io/qt-5/qwidget.html#keyReleaseEvent for the relevant key even if you have not released the key. You can not stop the events from being sent since they come directly from the windowing system. What you can do however is to check the autoRepeat() http://doc.qt.io/qt-5/qkeyevent.html#isAutoRepeat function in your key event handler and just ignore the key event if it was generated by an auto-repeating key.
See the following example for an illustration:
#include <QtWidgets>
class Widget : public QWidget
{
public:
Widget()
{
setFocusPolicy(Qt::StrongFocus);
}
void keyPressEvent(QKeyEvent *event)
{
if (event->isAutoRepeat()) {
qDebug() << "keyPressEvent ignore";
event->ignore();
} else {
qDebug() << "keyPressEvent accept";
event->accept();
}
}
void keyReleaseEvent(QKeyEvent *event)
{
if (event->isAutoRepeat()) {
qDebug() << "keyReleaseEvent ignore";
event->ignore();
} else {
qDebug() << "keyReleaseEvent accept";
event->accept();
}
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
Widget box;
box.show();
return app.exec();
}
How can I capture events for the delegate in my own class?
It is not possible to capture events for the delegate in a custom class. You need to reimplement the eventFilter() http://doc.qt.io/qt-5/qstyleditemdelegate.html#eventFilter for the delegate in order to grab its events. This is necessary because the delegate installs an event filter on the editor for the cell after the external event filter is installed, meaning it is always going to get the event first.
How can I ensure that a horizontal scrollbar and not an ellipse shows up when resizing a column smaller than its content in a QTreeView ?
To ensure that a scrollbar shows up instead of an ellipse when resizing a column smaller than its content in a QTreeView http://doc.qt.io/qt-5/qtreeview.html, then you need to call
setResizeMode(relevantColumn, QHeaderView::ResizeToContents)
on the header of your tree, so that the section is resized to its optimal size. You also need to call
setStretchLastSection(false)
if your tree only contains one column.
See the documentation:
http://doc.qt.io/qt-5/qheaderview.html#ResizeMode-enum http://doc.qt.io/qt-5/qheaderview.html#stretchLastSection-prop
See the following example for a demonstration:
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QTreeWidget tree;
tree.setColumnCount(1);
tree.setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
tree.header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
tree.header()->setStretchLastSection(false);
QStringList list = {"An item in a QTreeWidget with some text"};
QTreeWidgetItem *item = new QTreeWidgetItem(&tree, list);
tree.show();
return
}
Why doesn't Eclipse know about some of Qt's symbols / class names?
You might need to increase the maximal memory used by CDT's indexer:
- CDT 4.0: Window->Preferences->C++->Indexer*
and raise the 'Cache limits'.
- CDT 3.1: Window->Preferences->C++->Parser,*
and raise the 'CodeReader Buffer Size'.
You probably also want to run Eclipse with a higher memory limit, so call eclipse from the command line, with e.g.:
eclipse -vmargs -Xmx1000M
Does Qt provide an API for opening/saving encrypted files?
Qt does not offer encryption for opening/saving files, you will need to use a 3rd party library to manage this.
Example of how to style QToolBox with QStyle
The following is an sample subclass of QWindowsXPStyle() http://doc.qt.io/qt-5/qwindowsxpstyle.html to show how a QToolBox http://doc.qt.io/qt-5/qtoolbox.html can be styled.
#include <QtWidgets>
class MyStyle : public QWindowsXPStyle
{
public:
MyStyle() : QWindowsXPStyle() {}
void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter,
const QWidget *widget = nullptr) const override
{
if (element == CE_ToolBoxTab) {
const QStyleOptionToolBox *tb = qstyleoption_cast<const QStyleOptionToolBox *>(option);
painter->save();
painter->setBrush(QBrush(Qt::darkBlue));
painter->drawRoundedRect(option->rect.x() + 10, option->rect.y(), option->rect.width() - 20,
option->rect.height(), 10.0, 5.0);
painter->setPen(Qt::white);
painter->drawText(option->rect.x() + 15, option->rect.y() + 15, tb->text);
painter->restore();
} else {
return QWindowsXPStyle::drawControl(element, option, painter, widget);
}
}
};
int main(int argc, char **argv)
{
QApplication a(argc, argv);
a.setStyle(new MyStyle);
QToolBox tb;
tb.addItem(new QPushButton("A"), "Test");
tb.addItem(new QPushButton("B"), "Test 2");
tb.show();
return a.exec();
}
How can we create a binary on Leopard that runs on both 10.4 and 10.5?
When creating an application on Leopard , then in order for the application to run on both 10.4 and 10.5 then you need to set the *QMAKE_MACOSX_DEPLOYMENT_TARGET* to 10.4 in your .pro file as follows:
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4
This is documented here http://doc.qt.io/qt-5/deployment-mac.html#mac-os-x-version-dependencies.
Note that if you are using native calls then you will have to add checks yourself to ensure that it works correctly for all versions of the operating system. You can for example use
QSysInfo::MacintoshVersion < QsysInfo::MV_10_5
or check if the function pointer is non-zero. This will not be necessary when only using the Qt API as Qt does such checks for you.
Note that a Qt application compiled against 10.4 should run fine on 10.5.
My Windows build of Qt stops and complains that one of the plugins can't be opened. What's wrong ?
This problem is most likely related to you having had a previous version of Qt installed or that a Qt application that uses the named plugin is still running. Open the task manager and close down all Qt applications and restart the build. If this does not help, then try deleting the plugin dll explicitly and restart the build. This should solve the problem.
How can I prevent the text in a QComboBox's dropdown from being clipped when the QComboBox is smaller than the text?
To ensure that the text in the QComboBox's http://doc.qt.io/qt-5/qcombobox.html view does not get clipped when the QComboBox is resized to a smaller width than the width of the text in the view, you can call
view->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
which stops the view from being smaller than its sizeHint() http://doc.qt.io/qt-5/qcombobox.html#sizeHint. See the documentation on size policies http://doc.qt.io/qt-5/qsizepolicy.html#Policy-enum.
See the following example for a demonstration:
#include <QtWidgets>
class MyWidget : public QWidget
{
public:
MyWidget(QWidget *parent) : QWidget(parent)
{
QVBoxLayout *layout = new QVBoxLayout(this);
QComboBox *combo = new QComboBox(this);
combo->view()->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
layout->addWidget(combo, 1, 0);
combo->addItem(Combo box entry number 1);
combo->addItem(Combo box entry number 2);
combo->addItem(Combo box entry number 3);
setMinimumWidth(5);
}
};
int main( int argc, char **argv )
{
QApplication app( argc, argv );
MyWidget mw(0);
mw.show();
return app.exec();
}
Why does the 'New C++ Class' wizard miss most of the Qt classes in the 'Base Classes' list?
The wizard only provides classes that are known to the indexer - which, by default, only parses headers that are somehow reachable via includes in the projects header and source files. So, to have a Qt class in the 'New C++ Class' wizard you have to either include its header in one of your source or header files, or check the 'Index all files' checkbox in the global or project specific 'Indexer' settings (CDT 4.0 only).
How can I sort a QComboBox?
You can get hold of the combobox's model using model() http://doc.qt.io/qt-5/qcombobox.html#model and then call sort() http://doc.qt.io/qt-5/qabstractitemmodel.html#sort on the model.
Alternatively, you can use a proxy model http://doc.qt.io/qt-5/qsortfilterproxymodel.html.
Which compiler and debugger can I use with the Eclipse C++ Integration on Windows?
The Eclipse Integration for C++ supports both gcc provided with MinGW and cl.exe provided with Visual Studio. The Eclipse CDT plugin only supports gdb as a debugger however, so you have to use gcc as a compiler to be able to debug in Eclipse. For cl.exe it is possible to build release and debug versions in Eclipse, but it will not be possible to debug it.
When using fromWinHBITMAP() to create my pixmaps, they appear with a black background. What's wrong ?
If you pass in QPixmap::NoAlpha http://doc.qt.io/qt-5/qpixmap.html#HBitmapFormat-enum as the format to fromWinHBITMAP() http://doc.qt.io/qt-5/qpixmap.html#fromWinHBITMAP then all pixels with transparency will have an undefined value, for instance black.
If the format you pass in to fromWinHBITMAP() is QPixmap::PremultipliedAlpha option the pixel data must be in a premultiplied alpha format, otherwise the results will be undefined. QPixmap expects opaque pixels to be in the form 0xFFrrggbb, where the alpha byte is set to 255. If your pixels are in the form 0x00rrggbb, having an alpha of 0 then the image will not look correct.
If you created your pixel data using GDI functions its likely that you ended up with pixels in the form 0x00rrggbb as GDI will unset the alpha channel of all pixels it touches. You can work around this by manually patching up the alpha channel, afterwards or by only using GDI functions that support a proper alpha channel, like AlphaBlend.
Is it possible to have transparent Qt widgets on top of a QOpenGLWidget?
Qt provides a way to paint to an OpenGL context, but this is in the end painted separately from Qt and the two painting systems are not synchronized, so Qt cannot compose (semi-)transparent images on top of a QOpenGLWidget. At best, you can have opaque widgets on top of the QOpenGLWidget, but even then you may experience some flicker due to the painting being asynchronous.
Where do I find the resource editor in the integrated Qt Designer when using the Qt Eclipse Integration?
The Qt Eclipse Integration comes with a full editor for resource files. Just double click on the resource file in the Projects view. The integrated Qt Designer doesn't come with an extra resource editor.
There is no automatic way to redirect the commands in a QMainWindow's http://doc.qt.io/qt-5/qmainwindow.html menu to the current widget. If you would like e.g the Copy command to be redirected to the current widget, then you can listen for the QApplication::focusChanged() http://doc.qt.io/qt-5/qapplication.html#focusChanged signal and connect that signal to a slot which determines which actions should be executed for the current widget.
How do I find out why my mouse and keyboard work in QVFb, but not on my target system?
Keyboard and mouse problems should always be debugged on the Linux frame buffer not in QVFb as QVFb uses X keyboard and mouse drivers.
To debug on the Linux frame buffer, run the application in a console on your desktop system, with the option: -display LinuxFb instead of -display QVFb.
How can I specify the spacing between the text and the icon for an item in a view?
In order to specify the margin between the decoration and the text for an item in a view, you can subclass the style and reimplement pixelMetric() http://doc.qt.io/qt-5/qstyle.html#pixelMetric to return the value you want for PM_FocusFrameHMargin http://doc.qt.io/qt-5/qstyle.html#PixelMetric-enum and/or PM_FocusFrameVMargin. Alternatively, you can reimplement paint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#paint for the item delegate to draw the margins as you want.
The following example demonstrates how this can be done by reimplementing pixelMetric():
#include <QtWidgets>
class Style: public QWindowsStyle
{
public:
Style() {}
int pixelMetric(PixelMetric metric, const QStyleOption *option = nullptr,
const QWidget *widget = nullptr) const override
{
if (metric == PM_FocusFrameHMargin) {
return 10;
} else {
return QWindowsStyle::pixelMetric(metric, option, widget);
}
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QTreeWidget tree;
tree.setStyle(new Style());
QPixmap pix(12, 12);
pix.fill(Qt::red);
QTreeWidgetItem *item1 = new QTreeWidgetItem(&tree);
item1->setText(0, "first");
item1->setIcon(0, QIcon(pix));
QTreeWidgetItem *item2 = new QTreeWidgetItem(&tree);
item2->setText(0, "second");
item2->setIcon(0, QIcon(pix));
tree.show();
return app.exec();
}
Does qmake have support for pkg-config?
Yes, simply add link_pkgconfig to the CONFIG entry in your .pro file and then add pkg-config configurations to the PKGCONFIG variable, e.g:
CONFIG +=link_pkgconfig
TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .
PKGCONFIG = gtk+-2.0
# Input
SOURCES += main.cpp
See the documentation http://doc.qt.io/qt-5/qmake-project-files.html#configuration-features.
How can I align the text and icons in an itemview?
You can align the text and icons in your itemview by subclassing the itemview and reimplementing viewOptions() http://doc.qt.io/qt-5/qabstractitemview.html#viewOptions to return the alignment you want for the QStyleOptionViewItem http://doc.qt.io/qt-5/qstyleoptionviewitem.html.
The example below demonstrates how this can be done.
#include <QtWidgets>
class ListWidget : public QListWidget
{
public:
ListWidget()
{
QListWidgetItem *item1 = new QListWidgetItem("one");
QListWidgetItem *item2 = new QListWidgetItem("two");
QListWidgetItem *item3 = new QListWidgetItem("three");
addItem(item1);
addItem(item2);
addItem(item3);
}
QStyleOptionViewItem viewOptions() const override
{
QStyleOptionViewItem item;
item.init(this);
item.displayAlignment = Qt::AlignRight;
return item;
}
};
int main(int argc, char** argv)
{
QApplication app(argc, argv);
ListWidget listWidget;
listWidget.show();
return app.exec();
}
How can I change the margins of my QTextDocument?
In order to specify the margins used by the whole document you can follow these steps:
- Get the root frame that contains the document using QTextDocument::rootFrame() http://doc.qt.io/qt-5/qtextdocument.html#rootFrame
- Then get the QTextFrameFormat through QTextFrame::frameFormat() http://doc.qt.io/qt-5/qtextframe.html#frameFormat.
- Then call QTextFrameFormat::setMargin() http://doc.qt.io/qt-5/qtextframeformat.html#setMargin with the desired value.
In order to specify individual margins (independently) for each block of text, you can use the QTextBlockFormat http://doc.qt.io/qt-5/qtextblockformat.html#setTopMargin set margin functions.
The example below demonstrates how to set margins for the entire document and also how to set the margins for individual blocks.
#include <QtWidgets>
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QTextEdit edit;
edit.setText("The QTextEdit widget is an advanced editor that supports "
"formatted rich text. ");
edit.append("It can be used to display HTML and other rich document formats.");
QTextDocument * doc = edit.document();
QTextCursor cursor(doc);
cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
//cursor.movePosition(QTextCursor::Start, QTextCursor::KeepAnchor);
#if 1
QTextBlockFormat tbf = cursor.blockFormat();
tbf.setLeftMargin(100);
tbf.setTopMargin(100);
cursor.setBlockFormat(tbf);
#else
QTextFrame *tf = doc->rootFrame();
QTextFrameFormat tff = tf->frameFormat();
tff.setMargin(50);
tf->setFrameFormat(tff);
#endif
edit.show();
return app.exec();
}
Is is possible to run Qt applications on Windows XP Embedded ?
This should work since the Windows API is the same for Windows XP and Windows XP Embedded and since they are binary compatible, but it is not supported or tested by us.
I use a shortcut for interacting with a widget in my QTest::keyClick() function and the test fails. What can be wrong?
The problem is likely to be that you have not called show() http://doc.qt.io/qt-5/qwidget.html#show on your widget. If the widget is not visible, the shortcut does not actually behave correctly. You wouldn't typically have a shortcut that works for a non visible widget, so you should show your widget to get this test to pass.
How can I change the icon for the sort indicator and its position in a QHeaderView?
In order to change the icon and position for the sort indicator in a QHeaderView http://doc.qt.io/qt-5/qheaderview.html, you can subclass the style and reimplement drawPrimitive() http://doc.qt.io/qt-5/qstyle.html#drawPrimitive to draw the sort indicator using the icon and position you want.
#include <QtWidgets>
class Style: public QWindowsStyle
{
public:
Style () {}
void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
QPainter *painter, const QWidget *widget = nullptr) const
{
if (element == PE_IndicatorHeaderArrow ) {
const QStyleOptionHeader *headerOption =
qstyleoption_cast<const QStyleOptionHeader *>(option);
int x, y, width, height;
option->rect.getRect(&x, &y, &width, &height);
QPixmap pixmap;
if (headerOption->sortIndicator == QStyleOptionHeader::SortUp)
pixmap.load("arrow_up.png");
else
pixmap.load("arrow_down.png");
painter->save();
painter->drawPixmap(x+width,y+height,pixmap);
painter->restore();
} else
QWindowsStyle::drawPrimitive(element, option, painter, widget);
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QTableWidget table(2,2);
QTableWidgetItem *item1 = new QTableWidgetItem("1");
QTableWidgetItem *item2 = new QTableWidgetItem("2");
table.setItem(0,0, item1);
table.setItem(1,0, item2);
table.setSortingEnabled(true);
app.setStyle(new Style());
table.show();
return app.exec();
}
Alternatively, you can use a stylesheet to achieve this. See the documentation:
http://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qheaderview
When creating a library with Qt/Windows and using it in an application, then there is a link error regarding symbols which are in the library
When seeing errors like the following:
MyObj.obj : error LNK2019: unresolved external symbol public: static
struct QMetaObject const MyObj::staticMetaObject"
(?staticMetaObject@MyObj@@2UQMetaObject@@B) referenced in function class
MyObj * __cdecl qobject_cast<class MyObj *>(class QObject *)"
it is probably a result of the linker not finding the symbols from the library. You need to make sure that the symbols in your library are properly exported when the library is created. Subsequently imported when you are linking against the library, so you should have something like the following in a header file in your library:
#if defined TEST
#define TEST_COMMON_DLLSPEC __declspec(dllexport)
#else
#define TEST_COMMON_DLLSPEC __declspec(dllimport)
#endif
and use it in the classes that you wish to make available to the application like:
class TEST_COMMON_DLLSPEC MyObj : public QObject { ... };
Then add to your library's .pro file the following line so it knows that the symbols need to be exported in this case:
DEFINES += TEST
See the following wiki page http://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application for more information and a complete example.
How can I enable Edit and Continue in my Qt application?
Edit and Continue is not enabled by default for Qt projects since project files, created with qmake -tp vc contain the compiler switch */Zi*. To enable edit & continue, the right switch would be */ZI*.
To enable Edit & Continue in your .pro file, add the following to the .pro file:
QMAKE_CFLAGS_DEBUG += -ZI
QMAKE_CXXFLAGS_DEBUG += -ZI
Alternatively, you can enable Edit & Continue for your project inside Visual Studio, as follows:
- open the project settings
- select C/C++ -> General"
- set Debug Information Format to Program Database for Edit & Continue (/ZI)"
Is there a way to specify build dependencies for Visual Studio 2003 and 2005?
There are a couple of precautions you need to be aware of for the automatic dependency generation to work properly in MS Solution files. The attached example demonstrates how this can be done by following the steps below.
The dependencies are generated automatically, if
1a) there is a Lib/DLL project with the target name (the .lib is used, not the .dll of course) being that of what is used on link line of an other project in your solution
1b) there is a Exe project with the target name being that of what is used in a custom build-step of an other project in your solution
2) you don't use paths in the TARGET variable (use DESTDIR/DLLDESTDIR for that), like TARGET=$(SOME_VARIABLE)/myLib, won't work
3) if you have a special location for your libs, you specify the -Lmy/library/path and LIBS += mylib, instead of just using LIBS += my/library/path/mylib
4) the leaf projects are created before you generate the solution file. (You can use the recursive flag for qmake to do this, like qmake -tp vc -r [yourproject.pro]"
See also:
http://lists.trolltech.com/qt-interest/2006-07/thread00238-0.html
Are there seperate versions for CDT 3.1 and CDT 4.0?
No, the provided Qt Eclipse Integration package works with both CDT versions.
How can I move the origin of a QGraphicsScene to the top left corner of the view?
By default, the scene rectangle will be aligned to the view's center. So when the view gets larger, the scene will stay in the center of it. You can change the alignment of the scene with the QGraphicsView::setAlignment() http://doc.qt.io/qt-5/qgraphicsview.html#alignment-prop function.
How can I make the focus go from one cell to the next when hitting Enter?
In order to make the focus go from one cell to the next in a table when hitting Enter, you can reimplement the delegate's eventFilter() http://doc.qt.io/qt-5/qstyleditemdelegate.html#eventFilter and listen for QEvent::KeyPress http://doc.qt.io/qt-5/qevent.html#Type-enum. Then when the key is Enter, you can simply emit commitData(editor) and closeEditor(editor,QAbstractItemDelegate::EditNextItem) and return.
See the documentation on commitData() http://doc.qt.io/qt-5/qabstractitemview.html#commitData and closeEditor() http://doc.qt.io/qt-5/qabstractitemview.html#closeEditor
The following example demonstrates how this can be done:
#include <QtWidgets>
class MyItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
MyItemDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent)
{
installEventFilter(this);
}
bool eventFilter (QObject *editor, QEvent *event)
{
if (event->type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Return)
{
qDebug() << "Ate key press" << keyEvent->key();
emit commitData((QWidget*)editor);
closeEditor((QWidget*)editor, QAbstractItemDelegate::EditNextItem);
return true;
}
}
return QStyledItemDelegate::eventFilter(editor, event);
}
};
class TableWidget : public QTableWidget
{
Q_OBJECT
public:
TableWidget()
{
setItemDelegate(new MyItemDelegate());
setColumnCount(5);
setRowCount(5);
}
};
#include "main.moc"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
TableWidget box;
box.show();
return app.exec();
}
How to avoid that space is replaced with %20 when writing .ini files?
The only way to avoid space being replaced by %20 in the .ini file is to change the Qt code to not escape it, however the reason it is escaped is because the space character is not permitted as a key name in an ini file, see:
http://doc.qt.io/qt-5/qsettings.html#setIniCodec
What you should do here is either post-process the file to replace the escaped characters back . The other option is to register your own format with registerFormat() http://doc.qt.io/qt-5/qsettings.html#registerFormat.
Why doesn't my service created with QtService start?
In order for a service to start it is necessary to copy over the Qt dlls that are being used to the same directory as your application.exe. This is necessary to do because a service is started with only system environment variables set. i.e. QTDIR/bin is usually not part of that environment, so the system is most likely not able to locate the Qt dlls.
How to allow only a single column to be editable in a QTreeWidget?
The flags for QTreeWidgetItems http://doc.qt.io/qt-5/qtreewidgetitem.html are set for the entire item and all columns. For more flexibility, you may wish to use a QTreeView http://doc.qt.io/qt-5/qtreeview.html and QStandardItemModel http://doc.qt.io/qt-5/qstandarditemmodel.html, which lets you set the flags on individual items.
The documentation for QStandardItemModel contains a small example on how to create a tree model.
How do I make a combobox look similar to the one used in file dialogs?
The differences with the combobox used in a file dialog is that it shows a hierarchical view and although this is possible by padding items with space you run into problems when you have icons as well as text as the icons are not padded.
To achieve this functionality then you can set a QTreeView http://doc.qt.io/qt-5/qtreeview.html on the QComboBox http://doc.qt.io/qt-5/qcombobox.html and with a tweak of some of the settings you can get it to resemble the combobox used on a QFileDialog http://doc.qt.io/qt-5/qfiledialog.html.
The following is an example of how this can be done:
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication a(argc, argv);
QComboBox cb;
QTreeView *tv = new QTreeView;
tv->header()->hide();
QStandardItemModel *sim = new QStandardItemModel(1, 1);
QStandardItem *si = new QStandardItem;
QPixmap pix(16, 16);
pix.fill(Qt::red);
si->setText("C:\\");
si->setIcon(pix);
QStandardItem *childSi = new QStandardItem;
childSi->setText("windows");
pix.fill(Qt::blue);
childSi->setIcon(pix);
si->insertRow(0, childSi);
sim->setItem(0, 0, si);
cb.setModel(sim);
cb.setModelColumn(0);
tv->setRootIsDecorated(false);
cb.setView(tv);
cb.show();
QTimer::singleShot(0, tv, SLOT(expandAll()));
return a.exec();
}
NB: The call to QTimer::singleShot() is necessary as the expansion of the items needs to occur after the QComboBox and QTreeView are fully initalized after it gets shown.
Setting thread processor affinity in Linux
If you want to set CPU affinity per QThread http://doc.qt.io/qt-5/qthread.html, Qt does not provide an API do this, and you will need to use native platform calls. Qt provides a native handle to the currently running thread via the static method QThread::currentThreadId() http://doc.qt.io/qt-5/qthread.html#currentThreadId.
In Linux you will want to take a look at pthread_setaffinity_np() (in /usr/include/pthread.h) which lets you set the affinity of a thread. The id returned by QThread::currentThreadId() is the same as pthread_self(), so to change the affinity of the current thread, you could do something like this:
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(cpuNumber, &cpuset);
...
pthread_setaffinity((pthread_t) QThread::currentThreadId(), &cpuset);
You could just use pthread_self() as well, avoiding the cast.
Use of setCellWidget (in QTableWidget) and signal connections
The widgets set on the cells have nothing to do with the contents of the table, so you won't get signals from the table in such a case. If you have a row or column of widgets potentially emitting signals, and you want one slot to be notified of the row/column index of the widget that was triggered, then QSignalMapper http://doc.qt.io/qt-5/qsignalmapper.html#map could be the way to go.
The following example illustrates how this can be done:
main.cpp
#include <QtWidgets>
class CustomWidget : public QWidget{
Q_OBJECT
public:
CustomWidget(QWidget *parent = parent) : QWidget(parent)
{
table = new QTableWidget(7,4,this);
signalMapper = new QSignalMapper(this);
statusBar = new QStatusBar(this);
for (int i = 0; i< table->rowCount(); i++){
QComboBox *cb = new QComboBox();
cb->addItems((QStringList() << "Item 1" << "Item 2" << "Item 3"));
table->setCellWidget(i,2,cb);
connect(cb, SIGNAL(currentIndexChanged(int)), signalMapper, SLOT(map()));
signalMapper->setMapping(cb, i);
}
connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(demoSlot(int)));
setLayout(new QVBoxLayout);
layout()->addWidget(table);
layout()->addWidget(statusBar);
resize(400,300);
show();
}
public slots:
void demoSlot(int row){
QComboBox *cb = static_cast<QComboBox *>(table->cellWidget(row,2));
statusBar->showMessage(QString("Combobox changed at row %1, "\
"new value: %2").arg(row+1).arg(cb->currentText()), 5000);
}
private:
QTableWidget *table;
QSignalMapper *signalMapper;
QStatusBar *statusBar;
};
#include "main.moc"
int main( int argc, char** argv ){
QApplication app( argc, argv );
CustomWidget w;
w.show();
return app.exec();
}
When doing Qt | Open Solution from .pro file in Visual Studio 2005 I get an error saying the sln file is from a previous version of Visual Studio and must be converted, what can I do?
This problem can occur if you have both 2003 and 2005 installed, then these versions will conflict. What you need to do is either:
- Open the sln file in Visual Studio 2005 and you will get a conversion dialog. Answer yes in this dialog and the sln file will be converted to the 2005 format instead of 2003.
- Use the command prompt that can be found under *Start menu | Visual Studio 2005 | Command prompt*. Type *devenv /usenv* in this command prompt and this will ensure that the correct environment variables are set and that you should be able to use the Open Solution from .pro file option inside Visual Studio.
When building with Visual C++, it uses a different copy of a specified file that has the same name. How do I fix this?
This is a problem with nmake not respecting the path for the file when building in batch mode, it will find the first copy of the file in the paths and assume that is the right one. You can work around this problem by doing:
CONFIG += no_batch
in your pro file.
I am having problems displaying overlays on Linux with my NVIDIA card. The same code works on windows.
The NVIDIA driver only offers RGBA overlays. The default setting in QGLFormat is to use an index-based overlays. You can switch to RGBA overlays using this code:
QGLFormat f = QGLFormat::defaultOverlayFormat();
f.setRgba(true);
QGLFormat::setDefaultOverlayFormat(f);
How to add to the beginning of a QDomDocument?="<?xml version
'1.0'?> is added by creating a processing instruction as the
first child of the document:
QDomDocument doc;
doc.appendChild(doc.createProcessingInstruction(xml version =,'1.0'));
doc.appendChild(doc.createElement("hi"));
How can I do drag and drop in a widget?
Drag and drop support in Qt is centered around the QDrag http://doc.qt.io/qt-5/qdrag.html class that handles most of the details of a drag and drop operation.
In addition to creating a QDrag object, you need to reimplement dragMoveEvent() http://doc.qt.io/qt-5/qwidget.html#dragMoveEvent to accept the event and dropEvent() http://doc.qt.io/qt-5/qwidget.html#dropEvent to handle the data dropped on the widget. Finally dragEnterEvent() http://doc.qt.io/qt-5/qwidget.html#dragEnterEvent needs to be reimplemented to accept the event.
You also need to call
setAcceptDrops(true)
on the widgets that should be able to accept a drop.
For more information, read the general documentation http://doc.qt.io/qt-5/dnd.html on drag and drop:
The example below illustrates how this can be done.
#include <QtWidgets>
class MyDialog : public QWidget
{
Q_OBJECT
public:
MyDialog(QWidget *parent = nullptr);
public slots:
void makeDrag();
protected:
void dropEvent(QDropEvent *de);
void dragMoveEvent(QDragMoveEvent *de);
void dragEnterEvent(QDragEnterEvent *event);
};
class MyGroupBox : public QGroupBox
{
public:
MyGroupBox(QWidget *parent = parent) : QGroupBox(parent) {};
protected:
void dropEvent(QDropEvent *de);
void dragMoveEvent(QDragMoveEvent *de);
void dragEnterEvent(QDragEnterEvent *event);
};
MyDialog::MyDialog(QWidget *parent) : QWidget(parent)
{
QHBoxLayout *layout = new QHBoxLayout(this);
QPushButton *pushButton = new QPushButton(Click Me, this);
layout->addWidget(pushButton);
connect(pushButton, SIGNAL(pressed()), this, SLOT(makeDrag()));
MyGroupBox *box = new MyGroupBox(this);
layout->addWidget(box);
// Allow media to be dropped on the widget
setAcceptDrops(true);
box->setAcceptDrops(true);
}
void MyDialog::makeDrag()
{
QDrag *dr = new QDrag(this);
// The data to be transferred by the drag and drop operation is contained in a QMimeData object
QMimeData *data = new QMimeData;
data->setText(This is a test);
// Assign ownership of the QMimeData object to the QDrag object.
dr->setMimeData(data);
// Start the drag and drop operation
dr->start();
}
void MyDialog::dragMoveEvent(QDragMoveEvent *de)
{
// The event needs to be accepted here
de->accept();
}
void MyDialog::dragEnterEvent(QDragEnterEvent *event)
{
// Set the drop action to be the proposed action.
event->acceptProposedAction();
}
void MyDialog::dropEvent(QDropEvent *de)
{
// Unpack dropped data and handle it the way you want
qDebug(Contents: %s, de->mimeData()->text().toLatin1().data());
}
void MyGroupBox::dropEvent(QDropEvent *de)
{
// Unpack dropped data and handle it the way you want
qDebug(Contents: %s, de->mimeData()->text().toLatin1().data());
}
void MyGroupBox::dragMoveEvent(QDragMoveEvent *de)
{
// The event needs to be accepted here
de->accept();
}
void MyGroupBox::dragEnterEvent(QDragEnterEvent *event)
{
// Set the drop action to be the proposed action.
event->acceptProposedAction();
}
#include main.moc"
int main(int argc, char **argv)
{
QApplication a(argc, argv);
MyDialog d;
d.show();
return a.exec();
}
How can I tell qmake to have more than one target in a directory?
You can add your own targets in your .pro file using the variable *QMAKE_EXTRA_TARGETS*
For more information see:
http://doc.qt.io/qt-5/qmake-environment-reference.html#customizing-makefile-output
This will allow you to have several executables in the same directory.
How can I get hold of all of the visible items in my QTreeWidget?
In order to get a list of the visible items in a QTreeWidget http://doc.qt.io/qt-5/qtreewidget.html, then you can use itemAt(0,0) to get the first item, then use itemBelow() http://doc.qt.io/qt-5/qtreewidget.html#itemBelow to get the next and then do,
if (viewport()->rect().contains(visualItemRect(itemBelow(myItem))
to determine if it's actually on the viewport or not. See the documentation:
http://doc.qt.io/qt-5/qtreewidget.html#itemAt http://doc.qt.io/qt-5/qtreewidget.html#visualItemRect
The following example demonstrates how this can be done:
#include <QtWidgets>
QList <QTreeWidgetItem*>myList;
class TreeWidget : public QTreeWidget
{
Q_OBJECT
public:
TreeWidget(QWidget *parent = nullptr) : QTreeWidget(parent)
{
QStringList list;
list << "An item";
QTreeWidgetItem *item1 = new QTreeWidgetItem(list);
for (int i = 0; i < 100; i++) {
item1->addChild(new QTreeWidgetItem(item1, list));
}
QTreeWidgetItem *item2 = new QTreeWidgetItem(list);
QTreeWidgetItem *item3 = new QTreeWidgetItem(list);
QTreeWidgetItem *item4 = new QTreeWidgetItem(list);
addTopLevelItem(item1);
addTopLevelItem(item2);
addTopLevelItem(item3);
addTopLevelItem(item4);
item1->setExpanded(true);
}
public slots:
void test1()
{
QTreeWidgetItem *myItem = itemAt(0,0);
if (myItem) {
qDebug() << "I am visible";
myList << myItem;
}
while (itemBelow(myItem)) {
if (viewport()->rect().contains(visualItemRect(itemBelow(myItem)))) {
myItem = itemBelow(myItem);
myList << myItem;
qDebug() << "I am visible";
}else{
qDebug() << "I am visible";
myList << myItem;
break;
}}
qDebug() << myList.count() << " visible items" ;}
};
#include "main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
TreeWidget window;
window.show();
window.test1();
return app.exec();
}
Why is the debug version of my application so slow?
This is due to the fact that Microsoft Visual C++ .NET's debug version of the runtime libraries are slow, and by default Qt will link against the debug version of the runtime library if you configure Qt in debug mode. There is a workaround for this, simply do the following:
- Edit your qt\mkspecs\win32-msvc.net[2003/2005/2008]\qmake.conf file
- Where it states **-MDd** change it to be **-MD**
- Go into your qt directory
- nmake distclean
- Do configure -redo
- nmake
Then all that is left is to regenerate the Makefile for your application and rebuild it.
Why isn't the parent's font propagated to QAbstractItemView subclasses on Windows?
The reason the parent's font is not propagated to subclasses of QAbstractItemView http://doc.qt.io/qt-5/qabstractitemview.html is that it has its own font set in qapplication_win.cpp. This is to ensure that the itemviews have a font that matches what you would get in a native itemview on Windows.
To have the font propagated you need to set the font for the relevant class to an empty font in your QApplication http://doc.qt.io/qt-5/qapplication.html, e.g.:
QApplication::setFont(QFont(), "QAbstractItemView");
Another option is to set a stylesheet http://doc.qt.io/qt-5/stylesheet.html:
app.setStyleSheet("*{font ...}");
How does Qt::WA_PaintOnScreen relate to the backing store, widget composition and double buffering?
The behavior of the Qt::WA_PaintOnScreen http://doc.qt.io/qt-5/qt.html#WidgetAttribute-enum attribute is dependent on the platform it is used on.
On X11, setting this attribute will disable all double buffering and widget composition and let QPainter http://doc.qt.io/qt-5/qpainter.html draw directly onto the screen.
On Windows, this attribute is not supported by itself. It can only be used in combination with reimplementing QWidget::paintEngine() http://doc.qt.io/qt-5/qwidget.html#paintEngine to use custom paint engines. Reimplementing paintEngine() to return a null engine will give the user the option of drawing directly to the widget's HDC. Setting this flag will disable widget composition, but a double buffer will still be used for the widget.
On Mac OS X, double buffering and widget composition is done entirely by the windowing system, and setting this flag has no effect.
Does Qt Assistant support the MNG format?
Qt Assistant http://doc.qt.io/qt-5/assistant-manual.html does not support the MNG format (the animated PNG format).
I am getting linking errors when trying to link against msvcrtd.lib. And when linking against libcmt.lib the application crashes. What can I do ?
Qt is pre-built against the shared C runtime -MD(d), as this is the only C runtime that can be used safely in an environment where heap-allocated objects are passed around accross DLL boundaries (which is what you do all the time when creating QObjects or QWidgets - you create them in your heap, and usually pass them on as children of other objects so that Qt can take care of deleting them).
If you link Qt against the static libcmt.lib or if you link your Qt
applications against libraries that that are built against the static C
runtime library then you will get a mismatch of runtime libraries. This means
that there are two heaps in use and as a result if objects get passed from one
heap to another (i.e. from Qt to the application and vice versa) then memory
corruption will occur. You can usually catch this at build time, if you see a
link warning about default libraries then this is usually indicative of this
problem. The only way to resolve it is to ensure that everything is built in
the same mode.
When linking against msvcrtd.lib instead of libcmt.lib, then you might get linking errors reporting two unresolved symbols, __pctype, and ___mb_cur_max. msvcrtd.lib does contain those two symbols, however they are not automatically located. It is necessary to create a dummy source file that just references those two symbols:
extern C {
int __mb_cur_max;
unsigned short* _pctype;
int errno;
}
Why do I get hundreds of warnings when the compiler warning level is set to level 4 for MSVC?
We do not support building with warning level 4. The warnings generated at this level are often not valid, this is why we build at warning level 3.
The model does not have any information about the views, so your item delegate will have to handle this. If you want one of your views to have icons and not the other one, then you can reimplement QItemDelegate::drawDecoration() http://doc.qt.io/qt-5/qitemdelegate.html#drawDecoration and set the delegate on that view, e.g:
#include <QtWidgets>
class ItemDelegate : public QItemDelegate
{
public:
using QItemDelegate::QItemDelegate;
void drawDecoration(QPainter *painter, const QStyleOptionViewItem &option,
const QRect &rect, const QPixmap &pixmap) const override
{
QPixmap pix(22, 22);
pix.fill(Qt::red);
QItemDelegate::drawDecoration(painter, option, option.rect, pix);
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QWidget widget;
QHBoxLayout *layout = new QHBoxLayout(&widget);
QTableView *tableView = new QTableView(&widget);
tableView->setItemDelegate(new ItemDelegate());
QTableView *secondtableView = new QTableView(&widget);
QStandardItemModel *model = new QStandardItemModel;
model->insertRows(0, 4);
model->insertColumns(0, 4);
for (int row = 0; row < 4; row++) {
for (int col = 0; col < 4; col++) {
QModelIndex index = model->index(row, col);
model->setData(index, QVariant((row+1) * (col+1)).toString());
}
}
secondtableView->setModel(model);
tableView->setModel(model);
layout->addWidget(tableView);
layout->addWidget(secondtableView);
widget.show();
return app.exec();
}
Alternatively, you can reimplement QSytledItemDelegate::paint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#paint and draw the pixmap and the other details there.
How can I make both the item picture and the item text transparent in the drag icon so that user can see what is under the drag icon?
Whether or not transparent drag icons are supported is platform dependent. For instance Windows 2000 does not support this. So the simplest way to achieve this is to display what you want to drag in a toplevel QLabel http://doc.qt.io/qt-5/qlabel.htmland give this label a window opacity http://doc.qt.io/qt-5/qwidget.html#windowOpacity-prop
I can still insert numbers outside the range specified with a QDoubleValidator on a QLineEdit, is this a bug?
The validator will return an Intermediate http://doc.qt.io/qt-5/qvalidator.html#State-enum value for text that is a double but outside the range. The line edit will accept the intermediate values since it means that only a bit of editing is required to fix the value. This is because you might want to do something like pasting a number with 10 decimals with a validator that only allows 2 and then remove some of them.
The example below reimplements validate() http://doc.qt.io/qt-5/qvalidator.html#validate to make the validator more strict:
#include <qapplication.h>
#include <qmainwindow.h>
#include <qvalidator.h>
#include <qlineedit.h>
class MyDoubleValidator : public QDoubleValidator
{
public:
MyDoubleValidator(double bottom, double top, int decimals, QObject *parent = nullptr)
: QDoubleValidator(bottom, top, decimals, parent)
{}
QValidator::State validate(QString &input, int &pos) const override
{
if (input.isEmpty() || input == "."")
return Intermediate;
if (QDoubleValidator::validate(input, pos) != Acceptable) {
return Invalid;
}
return Acceptable;
}
};
class Widget : public QMainWindow
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr)
: QMainWindow(parent)
{
QLineEdit *edit = new QLineEdit( this );
setCentralWidget( edit );
edit->setValidator( new MyDoubleValidator( 0.0, 1.0, 3, edit ) );
}
};
#include main.moc"
int main( int argc, char **argv )
{
QApplication a( argc, argv );
Widget w;
w.show();
return a.exec();
}
You can call insertSeparator() http://doc.qt.io/qt-5/qmenu.html#insertSeparator in order to insert a separator before the Help action. Whether or not this separator is drawn, is style dependent however. It will not be drawn in the Windows(XP) Style. So you can either call
menuBar()->setStyle(new QMotifStyle())
or subclass the style and reimplement the stylehint() http://doc.qt.io/qt-5/qstyle.html#styleHint to return the SH_DrawMenuBarSeparator http://doc.qt.io/qt-5/qstyle.html#StyleHint-enum hint.
The following example demonstrates how this can be done:
#include <QtWidgets>
class Style : public QWindowsStyle
{
public:
Style() {}
int styleHint(StyleHint hint, const QStyleOption *option = nullptr, const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const
{
if (hint == QStyle::SH_DrawMenuBarSeparator)
return 1;
return QWindowsStyle::styleHint(hint, option, widget, returnData);
}
};
class MainWindow : public QMainWindow
{
public:
MainWindow()
{
QMenu *menu = new QMenu("File", this);
menu->addAction("An action");
QMenu *menu2 = new QMenu("Help", this);
menu2->addAction("Another action");
menuBar()->addMenu(menu);
menuBar()->addMenu(menu2);
//menuBar()->setStyle(new QMotifStyle()); //As an alternative to styleHint(), set the Motif style
menuBar()->setStyle(new Style());
menuBar()->insertSeparator(menu2->menuAction());
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
MainWindow box;
box.show();
return app.exec();
}
How can I turn off the debug and release Makefile generation for my application?
Simply add the following line to your pro file:
CONFIG -= debug_and_release
When setting a pixmap with an alpha on a widget, how can I remove the widget's gray edges that shine through?
In order to remove the non-transparent edges from the widget, you can set a heuristic mask on the pixmap. This will cause the outer most color to be removed where it is used in the pixmap. Then you can set the QBitmap http://doc.qt.io/qt-5/qbitmap.html which is returned from the call to createHeuristicMask() http://doc.qt.io/qt-5/qpixmap.html#createHeuristicMask as a mask on your widget. This will cause only the pixels of the widget for which bitmap has a corresponding 1 bit to be visible. Now you can set your pixmap on the widget, and only the pixels that correspond to where the mask has a bit set will be visible.
See the following example for a demonstration:
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QPixmap pixmap("pix_with_alpha");
QBitmap bm(pixmap.createHeuristicMask());
QSplashScreen splash(0);
splash.setMask(bm);
splash.setPixmap(pixmap);
splash.show();
return app.exec();
}
On the Mac you can call
qt_mac_set_Menubar_icons(false)
this will prevent the icons from showing up in the menu. See the documentation http://doc.qt.io/qt-5/exportedfunctions.html#void-qt-mac-set-menubar-icons-bool-enable.
Alternatively, you can iterate over the toolbar's toolbutton children and set an icon http://doc.qt.io/qt-5/qabstractbutton.html#icon-prop on them.
See the following example for a demonstration:
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QPixmap pix(15,15);
pix.fill(Qt::red);
QMainWindow box;
QAction *action = new QAction("First action", &box);
QAction *action2 = new QAction("Second action", &box);
QToolBar *toolBar = new QToolBar(&box);
toolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
toolBar->addAction(action);
toolBar->addAction(action2);
QList<QToolButton*> toolButtons = qFindChildren<QToolButton*>(toolBar);
for (int i = 0; i < toolButtons.size(); i++) {
QToolButton *button = (QToolButton*)toolButtons.at(i);
button->setIcon(pix);
}
QMenu *menu = new QMenu("File", &box);
menu->addAction(action);
menu->addAction(action2);
box.menuBar()->addMenu(menu);
box.addToolBar(toolBar);
box.show();
return app.exec();
}
Can you suggest a tool which we can use to track down memory leaks in Qt?
Qt doesn't limit your use of memory tools, so the best thing to do is to try out the different tools available to see what works best for you.
Internally, we use Purify on Windows and on Linux we use Valgrind.
How can I check which tab is the current one in a tabbed QDockWidget?
You need to find the QTabBar http://doc.qt.io/qt-5/qtabbar.html that exists for the tabbed dockwidgets and then simply call tabBar->currentIndex() http://doc.qt.io/qt-5/qtabbar.html#currentIndex-prop on it to find the current index and connect a slot to the tabbar's currentChanged() http://doc.qt.io/qt-5/qtabbar.html#currentChanged slot. The example below shows how you can do this.
#include <QtWidgets>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr)
: QMainWindow(parent)
{
QWidget *w = new QWidget(this);
setCentralWidget(w);
QVBoxLayout *layout = new QVBoxLayout(w);
QDockWidget *d0 = new QDockWidget("Dock 0");
d0->setFeatures(QDockWidget::NoDockWidgetFeatures);
d0->setWidget(new QTextEdit);
QDockWidget *d1 = new QDockWidget("Dock 1");
d1->setFeatures(QDockWidget::NoDockWidgetFeatures);
d1->setWidget(new QTextEdit);
QDockWidget *d2 = new QDockWidget("Dock 2");
d2->setFeatures(QDockWidget::NoDockWidgetFeatures);
d2->setWidget(new QTextEdit);
addDockWidget(Qt::LeftDockWidgetArea, d0);
addDockWidget(Qt::LeftDockWidgetArea, d1);
addDockWidget(Qt::LeftDockWidgetArea, d2);
tabifyDockWidget(d0, d1);
tabifyDockWidget(d1, d2);
// get the QTabBar
QList<QTabBar *> tabList = findChildren<QTabBar *>();
if(!tabList.isEmpty()){
QTabBar *tabBar = tabList.at(0);
tabBar->setCurrentIndex(1);
QString currentTab = tabBar->tabText(tabBar->currentIndex());
qDebug() << currentTab;
connect(tabBar, SIGNAL(currentChanged(int)), this, SLOT(testSlot(int)));
}
}
public slots:
void testSlot(int index)
{
qDebug() << "current tab is " << index;
}
};
#include "main.moc"
int main(int argc, char **argv)
{
QApplication a(argc, argv);
MainWindow mw;
mw.show();
return a.exec();
}
How can we remove properties from custom widgets in Designer?
You can remove properties from custom widgets in Designer using the QtDesignerPropertySheetExtension http://doc.qt.io/qt-5/qdesignerpropertysheetextension.html. This class allows you to manipulate a widget's properties which are displayed in Qt Designer's property editor.
You can setVisible(false) to hide the properties you want in Designer. See the documentation on setVisible() http://doc.qt.io/qt-5/qdesignerpropertysheetextension.html#setVisible.
How can I open my .html file in a browser?
You can use QDesktopServices http://doc.qt.io/qt-5/qdesktopservices.html to open a URL with the appropriate application for the system. So if you call
QDesktopServices::openUrl("http://qt.io/");
then a web browser as set by the system will be invoked to display the page. The actual web browser used depends on the system settings, so this could be Firefox, Internet Explorer, Opera or Safari etc.
If you need the page to be opened in e.g Firefox only, you can use QProcess http://doc.qt.io/qt-5/qprocess.html to start the browser and provide the appropriate arguments to Firefox.
How can I build executables/libraries in both release and debug mode on Windows?
Qt is built in both debug and release mode by default on Windows. When it comes to building your applications/libraries, you can specify
CONFIG += debug_and_release
in your .pro file (this is already on by default on Windows).
If you want only one configuration to be generated, then whatever is last on the CONFIG line with respect to debug and release will be the one that qmake generates. If you want it to build both configurations of your application/library, then you need to add:
CONFIG += build_all
to your pro file and then whenever you do nmake, both the debug and release versions will be built.
Who provides training for Qt?
A number of companies provide Qt training, in Asia, Europe and the US. See our training page http://www.qt.io/events/
Qt seems to ignore the key sequence Ctrl++, is this a valid key sequence that Qt should recognize?
This is due to the way the Qt accelerator system works. The SHIFT key transforms the key into another character, and since Qt's system is really character based, not key based, that sometimes becomes a problem. If the key sequence is changed to SHIFT+CTRL+= it will work on an EN keyboard-layout.
You can use the workaround in the example below to make the Ctrl++ accelerator work for English keyboard layouts as well. Note that this may not work for other keyboard layouts, but if you know which countries you are likely to target then you can add the appropriate shortcuts to solve this problem.
Note that only the use of standard shortcuts guarantees that the user will be able to use the shortcuts that the developer intended, a part from that it is recommended to use e.g the first character in a string in the shortcut see:
http://doc.trolltech.com/qkeysequence.html#keyboard-layout-issues
See the following example for a demonstration:
#include <QtWidgets>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow::MainWindow() : QMainWindow()
{
QAction* action = new QAction("Test", this);
QMenu *menu = menuBar()->addMenu("File");
menu->addAction(action);
connect( action, SIGNAL(triggered()), this, SLOT (giveOutput()));
action->setShortcut(Qt::SHIFT+Qt::CTRL+Qt::Key_Equal);
action->setShortcut(Qt::CTRL+Qt::Key_Plus);
}
public slots:
void giveOutput() {
qDebug("I was called"); }
};
#include "main.moc"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
MainWindow box;
box.show();
return app.exec();
}
How can I draw a question mark on an existing pixmap?
You open a painter on the pixmap and depending on how your question mark is represented, draw either the text string ?, or a polygon or a painter path describing the shape of a question mark.
How can I run a Qt application on a Unix machine that doesn't have X11 installed?
Qt is divided into several libraries. QtCore http://doc.qt.io/qt-5/qtcore.html, QtSql http://doc.qt.io/qt-5/qtsql.html, QtNetwork http://doc.qt.io/qt-5/qtnetwork.html and QtXml http://doc.qt.io/qt-5/qtxml.html don't link against X11 so you can use classes contained in this library and run your application on a machine that doesn't have X11 installed.
Is there a way to set the size of the icon for the items in my item view?
You can call setIconSize() http://doc.qt.io/qt-5/qabstractitemview.html#iconSize-prop on the view, this will readjust the icon sizes for the items to whatever you set it to.
Note that QIcon only scales down and not up, therefore the original pixmap should be as large as the max size you want to scale up to.
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QTableWidget box;
box.horizontalHeader()->setStretchLastSection(true);
QPixmap pix(50,50);
pix.fill(Qt::red);
QIcon icon(pix);
box.setIconSize(QSize(25,25));
QTableWidgetItem *itemOne = new QTableWidgetItem("one");
QTableWidgetItem *itemTwo = new QTableWidgetItem("two");
QTableWidgetItem *itemThree = new QTableWidgetItem("three");
itemOne->setIcon(icon);
box.setRowCount(5);
box.setColumnCount(5);
box.setItem(0,0,itemOne);
box.setItem(1,0,itemTwo);
box.setItem(2,0,itemThree);
box.show();
return app.exec();
}
When a signal is emitted, will all of the slots attached to it be executed before the emit returns? Or are the slots just scheduled to be executed whenever convenient?
Connections can be direct or queued. For direct connections, which is the default when connecting objects in the same thread, all of the slots will be executed before the emit returns. Slots connected to signals through a queued connection will be executed when control returns to the event loop.
The order of execution of the slots is undefined.
I have a complex control where I never want to draw a certain subcontrol, how can I achieve this in Qt 4?
In order to remove a subcontrol you need to subclass the style and reimplement drawComplexControl() http://doc.qt.io/qt-5/qstyle.html#drawComplexControl and make a copy of the style option and remove that subcontrol from the styleoption.
Here is an example where the frame is removed from a QGroupBox http://doc.qt.io/qt-5/qgroupbox.html
#include <QtWidgets>
class Style : public QWindowsStyle
{
Q_OBJECT
public:
Style() {}
void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = nullptr) const override {
if (const QStyleOptionGroupBox *group = qstyleoption_cast<const QStyleOptionGroupBox*>(option)) {
QStyleOptionGroupBox newGroupBox(*group);
newGroupBox.subControls &= ~SC_GroupBoxFrame;
QWindowsStyle::drawComplexControl(control, &newGroupBox, painter, widget);
} else {
QWindowsStyle::drawComplexControl(control, option, painter, widget);
}}};
#include "main.moc"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QWidget widget;
QVBoxLayout *layout = new QVBoxLayout(&widget);
QGroupBox *box = new QGroupBox(&widget);
box->setStyle(new Style());
box->setTitle("box");
layout->addWidget(box);
widget.show();
return app.exec();
}
What does it mean if the build fails with fatal error U1054
If installation of Qt/Windows fails with a message like this:
fatal error U1054: cannot create inline file 'C:\Documents and Settings\user\Local Settings\Temp nz00868'
then the Windows system ran out of names for temporary files, or tried to generate a temporary file that already exists. Delete your temporary files and restart your Qt installation to work around the problem. You might have to close all your other application to be able to do so.
How can I transfer shortcuts that are not available in the child window to the parent window?
You can create actions and set a shortcut to them and then add the actions to both the parent and the child as illustrated in the example below:
#include <QtWidgets>
class Parent : public QWidget
{
Q_OBJECT
public:
Parent()
{
dialog = new QDialog(this);
dialog->setWindowFlags(Qt::Window);
dialog->show();
dialog->setWindowTitle("Dialog");
QAction *a = new QAction(this);
a->setShortcut(QKeySequence("Ctrl+O"));
addAction(a);
connect(a, SIGNAL(activated()), this, SLOT(close()));
dialog->addAction(a);
}
private:
QDialog *dialog;
};
#include "main.moc"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
Parent box;
box.show();
return app.exec();
}
How can I stack the dockwidgets vertically in the top dock area?
We provide no API for stacking the widgets in the top dock area vertically, but you can achieve this however by performing a hack. Note that this is not supported and might not work in future versions of Qt as the internal API might change.
In the example below we subclass the private class QDockWidgetLayout and go over the main window's layout's children and cast them to our subclass and make sure to set the orientation to be vertical. Finally, we invalidate the layout to make sure it gets updated.
#include <QtWidgets>
class MyDL :public QDockWidgetLayout
{
public: MyDL(Qt::DockWidgetArea a, Qt::Orientation o) : QDockWidgetLayout(a, o)
{}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QMainWindow window;
QDockWidget *dock1 = new QDockWidget(&window);
QDockWidget *dock2 = new QDockWidget(&window);
QDockWidget *dock3 = new QDockWidget(&window);
window.addDockWidget(Qt::TopDockWidgetArea, dock2);
window.addDockWidget(Qt::TopDockWidgetArea, dock3);
window.addDockWidget(Qt::TopDockWidgetArea, dock1);
window.show();
QList<QLayout*> customLayout = qFindChildren<QLayout*>(window.layout());
for (int i = 0; i < customLayout.size(); i++)
{
MyDL *dl = (MyDL *)customLayout.at(i);
dl->QDockWidgetLayout::orientation = Qt::Vertical;
dl->invalidate();
}
return app.exec();
}
How can I create transparent labels and buttons where the window's background pixmap shines through the label?
The label will be transparent by default, so the background pixmap of the parent will shine through the label. For the buttons you need to fill the QPalette::Button http://doc.qt.io/qt-5/qpalette.html#ColorRole-enum color role to have no brush. Note that changing the palette will not work for all styles, it will for example not work for the XP and MacStyle which are pixmap based. For these styles you will have to draw this yourself in the paintEvent() http://doc.qt.io/qt-5/qlabel.html#paintEvent or set a style that supports this on the button.
See the following example:
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QPixmap pixmap(200, 200);
{
QPainter p(&pixmap);
p.fillRect(0, 0, 200, 200, QRadialGradient(100, 100, 100, 150, 150));
}
QWidget parent;
QPalette ppal = parent.palette();
ppal.setBrush(parent.backgroundRole(), pixmap);
parent.setPalette(ppal);
QWidget *wid = new QWidget(&parent);
QLabel *label = new QLabel("Testing 1, 2, 3, 4, 5, 6, 7, 8, ....", wid);
QPushButton *button = new QPushButton(wid);
button->setText("Button");
button->setAutoFillBackground(false);
QPalette pal = button->palette();
pal.setBrush(QPalette::Button, Qt::NoBrush);
button->setPalette(pal);
QVBoxLayout *layout = new QVBoxLayout(wid);
layout->addWidget(label);
layout->addWidget(button);
label->setFont(QFont("Arial", 30));
parent.show();
parent.resize(300, 200);
int ret = app.exec();
return ret;
}
My Designer plugin isn't loaded in Designer on Windows, even though I get the complied dll and lib. What's going on?
You need to make sure your plugin has the same configuration as the Qt library and see if it shows up in Qt Designer http://doc.qt.io/qt-5/designer-manual.html then. When Qt is configured to build in both debug and release modes which is the default on Windows, then Qt Designer will be built in release mode, so in this case your plugin needs to be built in release mode too. When loading plugins they need to have the same configuration as the application and the Qt library that the application is using.
Why are .pro files parsed three times?
This is by design. The default configuration on Windows is debug_and_release, and this results in qmake parsing the .pro file multiple times: once for debug, once for release, and once for the master makefile. Note that qmake also generates three files:
- Makefile
- Makefile.debug
- Makefile.release
On Redhat systems I get some Japanese characters displayed correctly but not all of them. How do I fix this?
On Redhat systems, when some of the Japanese characters are displayed correctly, but the rest are not, this indicates that Redhat was installed without Japanese font support. The only way to fix this is to install Japanese support. Then all Japanese characters should be visible just fine.
How do I get a non-rectangular or transparent widget?
Use QWidget::setMask() http://doc.qt.io/qt-5/qwidget.html#setMask.
Warning: Non-rectangular widgets are slow on some platforms.
How can I temporarily disable tooltips in a QTreeWidget?
You can reimplement QAbstractItemView::viewportEvent() http://doc.qt.io/qt-5/qabstractitemview.html#viewportEvent and handle the tooltip events the way you want there. Alternatively, you can install an event filter http://doc.qt.io/qt-5/qobject.html#eventFilter and handle the tooltip events there.
I am unable to set a fixed size on my dialog, how can I do this?
If your dialog does not have a layout, then you can simply call setFixedSize() http://doc.qt.io/qt-5/qwidget.html#setFixedSize on it. If your dialog does have a layout, then you need to call
layout()->setSizeContraint(SetFixedSize)
This will take any changes of the size hint into consideration, i.e. when the user moves a toolbar from top to left in the window, then the fixed height will be smaller, but the fixed width will be bigger to take this into account.
I change the background color of my child widgets, but the color does not change. What's wrong?
To make real subwidget transparency possible, the widgets are transparent per default. If you want to change this then you need to set autoFillBackground http://doc.qt.io/qt-5/qwidget.html#autoFillBackground-prop to true in order to allow child widgets to have a different background color than the parent.
Building Qt with MinGW fails
If building Qt or Qt programs fails with something like the following errors:
_cd tools\moc && c:/MinGW/bin/mingw32-make.exe_
_/usr/bin/sh: cd: toolsmoc: No such file or directory_
Make sure sh.exe is not in your path. make will use sh.exe instead of Windows' standard shell if sh.exe is in the path. Unfortunately sh.exe does not understand Windows-style paths and discards the separator. There's not much Qt can do to work around this make feature. Both Cygwin and MSYS provide sh.exe. Avoid MSYS while building Qt or Qt programs.
I am trying to build Qt on the Mac with the -universal flag specified, but it fails. What's wrong?
If you are building Qt on a PowerPC you need to specify the sdk path as well as the universal flag because the default libraries installed on Tiger do not include Intel, i.e:
-universal -sdk /path/to/MacOSX10.4u.sdk
If you don't specify the sdk path on a PowerPC then it will fail giving a warning like:
/usr/lib/gcc/i686-apple-darwin8/4.0.1/libstdc++.dylib does not
contain an architecture that matches the specified -arch flag: i386
You also need to specify the sdk in the .pro file when you are building your application. Add:
QMAKE_SDK_PATH = /path/to/MacOSX10.4u.sdk
When using Qt with STL it crashes with a memory access exception, how do I fix this?
If this happens, then the problem is usually either one of two things:
- A mismatch of runtime libraries - If you have built Qt in release mode and
your application in debug mode this means that it will be using two different runtime libraries. A release C runtime for Qt and a debug C runtime for your application. This means that there are two heaps in use and as a result if objects get passed from one heap to another (i.e. from Qt to the application and vice versa) then memory corruption will occur. You can usually catch this at build time, if you see a link warning about default libraries then this is usually indicitive of this problem. The only way to resolve it is to ensure that Qt and your application is built in the same mode. With Qt 4, by default both versions are available so you should not encounter this problem.
- The environment variables are not set correctly - If you have more than
one compiler installed on your machine, then it is possible that the environment variables (particularly INCLUDE and LIB) are not pointing to the right compiler. You should ensure that the environment variables match the compiler that you are actually using to build and run the application.
How can I add SSL support to my Qt application?
For legal reasons, Qt doesn't ship with SSL. Only the Qt module that wraps SSL is included in the binaries. See the documentation http://doc.qt.io/qt-5/requirements.html.
If you want to include SSL support, you must first obtain OpenSSL from here http://www.openssl.org/ and make sure the paths to its include and lib directories are available in the environment when building Qt. OpenSSL support should then be available by default when building Qt.
How can I have richtext in my QTableView?
The standard table view doesn't support rich text formatting, but you can set an item delegate on the view and reimplement its paint function so that it will allow rich text. The paint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#paint function below illustrates how this can be done and can be used with the qt\examples\itemviews\spinboxdelegate example http://doc.qt.io/qt-5/4.7/itemviews-spinboxdelegate.html :
void SpinBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QTextDocument document;
QVariant value = index.data(Qt::DisplayRole);
if (value.isValid() && !value.isNull()) {
QString text("<span style='background-color: lightgreen'>This</span> is highlighted.");
text.append(" (");
text.append(value.toString());
text.append(")");
document.setHtml(text);
painter->translate(option.rect.topLeft());
document.drawContents(painter);
painter->translate(-option.rect.topLeft());
}
}
You can find more information on the text formatting in our documentation http://doc.qt.io/qt-5/richtext-html-subset.html
Can I use Windows APIs together with Qt? The compiler complains about redefinition of HDC etc.
Yes, you should be able to use the Windows APIs alongside Qt without any problem. If you get such compilation failures, just make sure that you include the Qt header files before windows.h or any other Windows header files in your code.
Is there a limit to the number of widgets I can create on Windows ?
Qt does not have any limits in that respect, but of course the operating system/graphics subsystem does and Qt cannot work around those. For example, on Windows 2000/XP you are usually limited to about 10000 GDI objects, which includes widgets, pixmaps, fonts and cursors etc.
In Qt 4 widgets or pixmaps do not use GDI objects. Widgets still have some system dependent part, the window id, which also limits us in the number of widgets one can create at the same time. Since Qt 4.4 we only allocate window id's for toplevel widgets or widgets that otherwise explicitly need the window id. The effect of this is that you should seldomly reach the limit.
When the limit is reached, it is most likely because the application uses too many pixmaps, fonts, widgets or cursors and keep them alive at the same time. The only way to work around these limitations is to minimize the simultaneous use of these types of objects, such as deleting dialogs immediatly after they have been used and hidden, etc.
A QTreeWidget is sorted alphabetically by default, how can I change this behavior, e.g to sort numerically instead ?
You can achieve this by subclassing QTreeWidgetItem and reimplementing QTreeWidgetItem::operator<() http://doc.qt.io/qt-5/qtreewidgetitem.html#operator-lt to perform e.g numeric sorting rather than string comparison.
Note that setSortingEnabled http://doc.qt.io/qt-5/qtreeview.html#sortingEnabled-prop should be set to true after you insert the items, otherwise the insertion will be slow as each item that gets inserted will get sorted. Alternatively, you can insert all of the items in one go using a list, see:
http://doc.qt.io/qt-5/qtreewidget.html#insertTopLevelItems
The following example illustrates how this can be done:
#include <QtWidgets>
class TreeWidgetItem : public QTreeWidgetItem
{
public:
TreeWidgetItem(QTreeWidget *tree) : QTreeWidgetItem(tree) {}
TreeWidgetItem(QTreeWidget * parent, const QStringList & strings)
: QTreeWidgetItem (parent,strings) {}
bool operator< (const QTreeWidgetItem &other) const
{
int sortCol = treeWidget()->sortColumn();
int myNumber = text(sortCol).toInt();
int otherNumber = other.text(sortCol).toInt();
return myNumber < otherNumber;
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QTreeWidget tree;
tree.setColumnCount(2);
TreeWidgetItem *item1 = new TreeWidgetItem(&tree);
item1->setText(0, "1");
TreeWidgetItem *item2 = new TreeWidgetItem(&tree);
item2->setText(0, "2");
TreeWidgetItem *item3 = new TreeWidgetItem(&tree);
item3->setText(0, "3");
QStringList list;
list << "10" << "6";
TreeWidgetItem *item4 = new TreeWidgetItem(&tree, list);
QStringList list2;
list2 << "20" << "7";
TreeWidgetItem *item5 = new TreeWidgetItem(&tree, list2);
tree.setSortingEnabled(true);
tree.show();
return app.exec();
}
Are there any books about Qt programming?
Yes, there are quite a few books on Qt, most of them are available from amazon.com. Check out the Qt Book list to find a list of known available Qt books.
How can I change the border color of a frame using a stylesheet?
In order to change the border color, you need to specify a px size in the stylesheet http://doc.qt.io/qt-5/stylesheet.html, e.g
browser->setStyleSheet("QTextBrowser {border: 1px solid red}");
The border is 0px by default, so in order for it to show up, you need to define a px size.
There are general rendering problems when I run my application on a machine that has a Matrox G450 graphics card. Other machines that don't use this card do not have this problem. Is there a way to workaround this?
This is due to a problem with the graphics card itself and not with Qt.
In order to workaround the problem, you need to disable one of the options on the card. There is an option on the Matrox G450 graphics card called **Use Bitmap Device Caching**. Disabling this should resolve the problem with the rendering.
The QPoint() http://doc.qt.io/qt-5/qpoint.html argument to the popup() http://doc.qt.io/qt-5/qmenu.html#popup function takes global screen coordinates as its argument. The position sent to a mouse event is always in the widgets local coordinates. Positions can be transformed between the different coordinate systems with either:
- QWidget::mapToGlobal() http://doc.qt.io/qt-5/qwidget.html#mapToGlobal
- QWidget::mapToParent() http://doc.qt.io/qt-5/qwidget.html#mapToParent
- QWidget::mapFromGlobal() http://doc.qt.io/qt-5/qwidget.html#mapFromGlobal
- QWidget::mapFromParent() http://doc.qt.io/qt-5/qwidget.html#mapFromParent
In the case with the mouse event, the correct way is to use the event's globalPos() http://doc.qt.io/qt-5/qmouseevent.html#globalPos function instead. Here is one way of doing it:
void CustomWidget::mousePressEvent(QMouseEvent *event) override
{
if (event->button() == RightButton)
menu->popup(event->globalPos());
}
You frequently say that you cannot add this or that feature because it would break binary compatibility. What does this mean, really?
Binary compatibility means that you can safely distribute your Qt programs dynamically linked to the Qt library. If the users of your program have a newer version of the Qt dynamic library installed (or later upgrade to one), your program will still work. This can save much time, network, disk, and memory resources and administration work, for both you and the users of your Qt-based programs.
Technically, this means, roughly ordered from least to most obvious:
- We cannot add reimplementations of virtual functions, unless it it safe
for older binaries to call the original implementation. This is because the compiler evaluates SuperClass::virtualFunction() calls at compile-time, not at link-time.
- We cannot add or remove virtual member functions. This would change the
size and layout of the vtbl of every subclass.
- We cannot change the type of any data members or move any data members
that can be accessed via inline member functions.
- We cannot change the class hierarchy, except to add new leaves.
- We cannot add or remove private data members. This would change the size
and layout of every subclass.
- We cannot remove public or protected member functions unless they are
inline.
- We cannot make a public or protected member function inline.
- We cannot change what an inline function does, unless the old version
continues working.
- We cannot change the access rights (i.e. public, protected or private) of
a member function. Some compilers mangle the access rights into the function name.
- We cannot change the signature of a function, this includes changing the
return type and adding a new parameter.
How can I generate .vcproj files recursively for a .pro file with the SUBDIRS template set?
You can create .vcproj files recursively by typing
qmake -tp vc -r
in the toplevel directory. Then the .vcproj files will be created in each subdirectory and the .sln file will be created in the main directory.
How can I get a HDC handle?
You can create a HBITMAP using GDI and then you can convert this to a QPixmap http://doc.qt.io/qt-5/qpixmap.html afterwards. See the documentation http://doc.qt.io/qt-5/qpixmap.html#fromWinHBITMAP for more information on how to do that.
MSVCRTD.lib(cinitexe.obj) : warning LNK4098: defaultlib msvcrt.lib conflicts with use of other libs; use /NODEFAULTLIB:library -- What does this mean and how can I fix it?
This happens because Qt is linked against the release version of the C runtime and your application is built with debug symbols. You need to rebuild Qt in debug mode or the application in release mode.
It is intentional that the dockwindow is hidden and not closed. You can delete the dockwindow by calling close() http://doc.qt.io/qt-5/qwidget.html#close in the hideEvent() http://doc.qt.io/qt-5/qwidget.html#hideEvent in addition to passing in the Qt::WA_DeleteOnClose http://doc.qt.io/qt-5/qt.html#WidgetAttribute-enum attribute. Another approach could be to call deleteLater() http://doc.qt.io/qt-5/qobject.html#deleteLater in the hideEvent(). You can not delete it in the hideEvent() as this will cause a crash.
Is there a limitation on Windows as to how many QRegions we can have?
Qt itself does not impose a limit on the number of QRegions http://doc.qt.io/qt-5/qregion.html, however since QRegion uses a GDI object on Windows, you are limited by the amount of GDI resources that are available to you on Windows. This varies depending on what version of Windows you are using.
How can I create a QDialog that has no minimize, maximize and close buttons in the titlebar?
You can achieve this by specifying a combination of window flags http://doc.qt.io/qt-5/qt.html#WFlags-typedef provided your window manager supports those flags.
The example below demonstrates how this can be done, if this example does not remove the buttons for you, then it is likely because your window manager does not support that, and there is nothing we can do about that in Qt unfortunately.
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QDialog box(0, Qt::WindowTitleHint);
box.show();
return app.exec();
}
How can I maintain several configurations using only one source tree?
This can be done by using shadow builds. Start with a clean Qt source directory. Create a folder for your custom configuration, and call configure from this directory using
../path/to/qtdir/configure -prefix $PWD <other options here>
This will allow you to maintain several configurations for one source.
Context menus behave differently from normal menus, pressing Alt will not show the underlines in a context menu. Instead you need to change one of the settings in the control panel to make them visible. On Windows 7 this can for example be done here:
- Control Panel / Ease of Access Center / Make the Keyboard easier to use*
Then you can find this option at the bottom of the window:
- Underline keyboard shortcuts and access keys*
Check this if you want the underlines to be displayed at all times. You will see the same behavior in e.g notepad
How to build pdb for release version of Qt?
In order to build .pdb files for the release version of Qt, simply add the required compiler parameter in the mkspec you use. For example for MSVC 2005, you'd modify <Qt path>\mkspecs\win32-msvc2005\qmake.conf and add the -zi flag to QMAKE_CFLAGS_RELEASE and the /DEBUG flag to QMAKE_LFLAGS_RELEASE, e.g
QMAKE_CFLAGS_RELEASE = -O2 -MD -zi
and
QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO /DEBUG
Now the compiler will create debug information and the linker will use it while linking.
Do you provide a tool for creating graphs?
We do not provide graphs, but you can paint them yourself using QPainter. An example of a chart is available in the Qt directory in :
examples/itemviews/chart
Since the release of Qt 4.2 this is greatly facilitated by the QGraphicsView classes, although these offer functionality beyond that required by a simple graph.
There are also 3rd party classes that provide such functionality. See:
http://sourceforge.net/projects/qwt/ http://www.kdab.com/products/kd-chart
I am unable to step into the Qt code in Visual Studio, what can the problem be?
If you configured Qt with debug symbols then this should work. In addition to letting you step into the code this will also give output from asserts, warnings etc.
Also make sure your project has *CONFIG+= debug* in the .pro file.
The other situation where the debugging would not work is when something is out of sync. You are using some libraries from previous builds for example. The best thing to do in this case is to clean out the old build by going to a command prompt and typing
nmake clean
configure -redo
nmake
in your Qt directory.
Why do ActiveQt controls no longer work after an upgrade to Internet Explorer 7?
The reason this happens is because Internet Explorer 7 has changed the security settings around. In order to make ActiveQt controls work in Internet Explorer you need to add the website that hosts the control to your *Trusted Sites* and *Enable Scripting For Unsigned Controls* for the Trusted Sites security level.
Do you support using Qt in the Cygwin shell on Windows?
We don't support the Cygwin shell with Qt, mainly because Cygwin uses different directory separators than the Windows ones, therefore our apps are not likely to work correctly. You should use the cmd shell instead.
When untaring the Qt package the following warning is seen Tar.gz file content file @Longlink with zero permission and size. How can this be resolved?
When untarring the Qt package with a different version of tar that is not the GNU tar, then the warning:
Tar.gz file content file @Longlink with zero permission and size
may be seen. This is because LongLink is used when creating the package and this is an extension to GNU's tar to allow filenames longer than 100 characters. Therefore the package can only be used with the GNU version of tar, not with the vendor version of tar.
The font Rendering is distorted on Windows, what could cause this problem?
Ensure that ClearType is enabled in Windows display properties. The location of the ClearType check box depends on which version of Windows is being used.
When I compile my Qt based program I get a parse/syntax error in one of Qt's header files. What's wrong?
The most common cause is that a header file you have included before the Qt header file defines a macro with a name that is used in the Qt header file. Examples we have encountered include Ok, ButtonMask, list, red, black, bool, raise and connect.
A standard trick for tracking down these kind of problems is to look at compiler output after preprocessing has been done (often done with a -E option) and compare the output with the header file where you get the error.
There are three common strategies for dealing with such problems, which may often be combined:
- Include the Qt header file first. This allows the other header file to #define the macro, and you cannot use Qt's function or enum.
- Include the other header files, then #undef the relevant macro, then include the Qt header files. For example:
</syntaxhighlight>
- define ButtonMask ButtonMask_hack
- include <offender.h>
- undef ButtonMask
- include <qmsgbox.h>
</syntaxhighlight> This allows you to use the function or enum in Qt, but not the macro in the other header file.
- Include the other header file in just one .cpp file (and no .h files) in
your application and encapsulate the functionality you need. This limits the scope of the conflict to just one .cpp file. Since this limits the system dependent code to one file, it also increases the portability of your code.
GNU STL is a special case. It defines two global enums, red and black, which are used by their internal red-black tree class. Unfortunately, they crash with Qt's global color objects named red and black. Here's a workaround:
#define red stl_red
#define black stl_black
#include <stl.h>
#undef red
#undef black
#include <qcolor.h>
How is configuration management handled?
Standard unix configure; make; make install procedure is used. Specifically, the configure step enables options then the Qt qmake tool builds makefiles, which then control the build process. The specifics of each applications are encapsulated in a simple 'project' file (eg. listing files appropriate for given configurations).
Why does a statically built Qt use the dynamic Visual Studio runtime libraries ? Do I need to deploy those with my application ?
Qt is built using the -MD(d) switch, which links against the dynamic C/C++ runtime libraries. This is necessary as we have experienced memory problems when using anything but the -MD(d) flag, and in general, it is recommended to use. You should not alter this flag yourself for your application, because it conflicts with how the Qt library is built if you change the flag to -MT. You should not change it for Qt either, since it is likely to cause problems.
Qt is still built statically when using the -static option though, meaning you do not need to distribute the Qt dlls when deploying your application. You will have to distribute the C runtimes though (if they don't already exist on the target machine), see our deployment documentation http://doc.qt.io/qt-5/deployment-windows.html#application-dependencies.
If you choose to change this setting anyway, then it can be done in the qmake.conf file for your qmakespec. Where it says *-MD* you need to change it to be *-MT*. For Visual Studio 2005 it is also necessary to change the relevant files in mkspecs/features to remove the call to mt.exe. As stated above, we can't support you with any problems you run into as a consequence of making these changes.
What do I need installed on my machine to begin using Qt Creator and/or the Qt SDK?
The Qt SDK contains all the Qt-related components you need to get started, however some platform-specific essentials are also required depending on the platform you're developing on.
- Windows: The Qt SDK contains everything you need.
- Linux: The essential components to build software, which typically include make tools, gcc compiler, gdb debugger and the libraries needed for standard development.
- Mac: Standard development tools like debugger, etc. The easiest way to get these is to install XCode.
When I read a XPM image into a QImage, is there a way I get determine which color is the transparent one?
You can have a look at the color table for the image. This is accessible through QImage::color() http://doc.qt.io/qt-5//qimage.html#color and then you can check for colors that have an alpha of 0.
How do I find out the properties of my Linux Frame Buffer?
Use the Linux command: *fbset*, often found in /usr/sbin/.
How can I find out where the contents of my Mac binary package is installed?
You can check where things are installed by going to the
- /Library/Receipts/Qt_*.pkg/Contents *
directory and doing a lsbom on Archive.bom in that directory.
How can I create a custom editor in my view?
You can create a delegate and set it on the view using setItemDelegate() http://doc.qt.io/qt-5/qabstractitemview.html#setItemDelegate. A delegate http://doc.qt.io/qt-5/qstyleditemdelegate.html allows the way items of data are rendered and edited to be customized.
Alternatively you can use QItemEditorCreatorBase http://doc.qt.io/qt-5/qitemeditorcreatorbase.html.
See the spinboxdelegate http://doc.qt.io/qt-5/itemviews-spinboxdelegate.html example for a demonstration on how to implement your delegate.
Purify complains about UMRs (Uninitialized Memory Reads) in the QGDict constructor? Is this a bug in Qt?
This is not a bug in Qt. You can safely ignore this message.
QGDict uses bit field members to save space. When QGDict initializes its members, bits are either set or cleared. To clear a bit on assembly level, a byte is first read, AND'ed with a mask and written back. Purify reports a UMR when reading the byte. The UMR depends on your compiler and compiler options.
We've seen such false UMRs in these places, among others, in Qt:
- QGDict::QGDict()
- QMenuData::QMenuData()
- QPushButton::init()
- QMenuItem::QMenuItem()
- QScrollbar::QScrollbar()
We've been in contact with PureAtria (now Rational), the maker of Purify, and they say this is a problem which cannot easily be solved. The only solution would be that the compiler first sets all bytes to zero before accessing the bits.
How is your double buffering implemented?
We use an approach commonly referred to as backing store. In this technique we maintain one pixmap per toplevel widget and each widget draws itself into this pixmap. Only when a widget changes does it update the contents of the toplevel pixmap. The effect of this is that on expose events the windowing system (or Qt) can copy the pixmap to screen rather than calling QWidget::paintEvent() (which can be costly), resulting in very fast updates when windows are moving on top of each other.
Is Qt binary compatible?
Qt is backwards binary and source compatible within each major release. This means that a program linked dynamically to e.g Qt 4.5.1 will continue running with Qt 4.5.3 without the need to recompile. Qt is not binary compatible between major versions such as Qt 2.x, Qt 3.x and Qt 4.x etc. Qt is also not forwards compatible, meaning that applications created with a newer version of Qt will not necessarily run or compile against older Qt versions.
How can I find out what image formats my application supports?
You can use QImageReader::supportedImageFormats() http://doc.qt.io/qt-5/qimagereader.html#supportedImageFormats for this.
Drawing dotted lines seems slow, do you have a solution for this?
When you are drawing dotted lines or lines that are of non zero width, these are slower than simple lines. One suggestion that could speed this up for you, is to instead of using a dotted line, use a pattern brush with Dense4Pattern as color for the pen and draw a solid line of width 0. This will give you the same result visually, but will use a faster path through the paint engine. Another alternative is to use an alpha color on the pen instead of a dotted line. This will be visually different, but usually looks as nice.
How can I paint outside the paintevent?
In Qt 4 it is not allowed to paint outside the paint event. The primary reason for this is that Mac OS X does not support it and it prevents us from doing widget composition which is one of the main features of Qt 4.1. What you can do instead is to do all your drawing to a QPixmap and draw this pixmap as part of your paint event.
How can I resize a QDockWidget programatically?
When you add the dock widget to the QMainWindow http://doc.qt.io/qt-5/qmainwindow.html, it becomes part of the main window's layout and any size you give is ignored. You can however reimplement the QWidget::sizeHint() http://doc.qt.io/qt-5/qwidget.html#sizeHint-prop for the widget contained in the QDockWidget http://doc.qt.io/qt-5/qdockwidget.html to give it a preferred size or you can call QWidget::setFixedSize() http://doc.qt.io/qt-5/qwidget.html#setFixedSize on it to give it a size that can't be changed.
Note that since QDockWidget acts as a wrapper for its child widget, custom size hints, minimum and maximum sizes and size policies have to be implemented in the child widget. QDockWidget will respect them, adjusting its own constraints to include the frame and title. Size constraints should not be set on the QDockWidget itself, because they change depending on whether it is docked; a docked QDockWidget has no frame and a smaller title bar.
See the following example for a demonstration:
#include <QtWidgets>
class Label : public QLabel
{
public:
Label(QWidget *parent) : QLabel(parent)
{
setAutoFillBackground(true);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
QPalette pal = palette();
pal.setBrush(QPalette::Window, Qt::red);
setText("The label");
setPalette(pal);
}
QSize sizeHint() const
{
return QSize(400, 500);
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QMainWindow box;
box.setCentralWidget(new QLabel("Central Widget", &box));
QDockWidget *dock = new QDockWidget(&box);
dock->setWidget(new Label(dock));
box.addDockWidget(Qt::TopDockWidgetArea, dock );
box.show();
return app.exec();
}
When I build Qt I see the following: *** [listboxeditor.h] Trace/BPT trap and it fails to build.
This is because your DYLD_LIBRARY_PATH is not set correctly, it needs to include the $QTDIR/lib directory.
How can I add widgets to my QFileDialog instance?
You can use the layout() http://doc.qt.io/qt-5/qwidget.html#layout function to get hold of the dialog's layout and add your widgets there. See the following example:
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QFileDialog box;
QPushButton *button = new QPushButton(&box);
button->setText("New button");
QGridLayout *layout = (QGridLayout*)box.layout();
layout->addWidget(button, 0, 0);
box.show();
return app.exec();
}
How can I draw text that is both filled and outlined?
If you want to draw text both filled and outlined, you can use QPainterPath http://doc.qt.io/qt-5/qpainterpath.html for this, for instance:
QPainterPath path;
path.addText(position, font, "Hello");
painter.setPen(pen);
painter.setBrush(brush);
painter.drawPath(path);
Purify found a memory leak in qapplication_x11.cpp. Why don't you clean up the XIM (X Input Method) structure?
This is to work around a bug in some versions of Xlib. The leak isn't harmful, it concerns only 400 bytes of memory which will be deallocated anyway when the application terminates.
You say I can program for multiple platforms with one source tree with Qt. Do I need cross-compilers or special tools?
Qt uses native compilers such as gcc (Linux) or Visual C++ (Windows) on the targeted platforms. There is no need for special cross-compilers or additional tools.
Are any benchmarking and performance measurement tools used?
We use a combination of complete instrumented quantification (Valgrind/ Cachegrind) and specific manual instrumentation (event timing).
Why can't Qt Mac for Cocoa be configured with -static?
There are two reasons:
- Qt has a nib it must load in order to interact correctly with the native menu bar. It is possible to copy the nib into the resource directory of the resulting bundle, but it is up to the developer to do this.
- Qt uses categories http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocCategories.html#//apple_ref/doc/uid/TP30001163-CH20-SW1
to extend capabilities of the certain Cocoa classes. These categories are lost when creating a static library. We are aware of a possible workaround(workaround) http://developer.apple.com/qa/qa2006/qa1490.html, but have not had a chance to try it out and support it.
We will evaluate and see if there is a possibility of supporting a static build with Cocoa in the future. For the time being it is not supported.
unixODBC FreeTDS qGetStringData: Error while fetching data
When installing unixODBC 2.2.14 and freeTDS 0.82 and executing a query like
select USER_ID from MY_TABLE
the following message will be issued:
qGetStringData: Error while fetching data ( [FreeTDS][SQL Server]Program type out of range )
The solution to this problem is to install the latest version of FreeTDS, as it now provides SQL W CHAR.
Why is my text not antialiased?
Text antialiasing in Qt is based on the underlying font system. If a font is not being antialiased it is most likely because it is a bitmap font or because the underlying system does not support it. On X11 for instance, Xft is required to draw antialised fonts.
It is possible to specify a style strategy to QFont http://doc.qt.io/qt-5/qfont.html, using QFont::StyleStrategy http://doc.qt.io/qt-5/qfont.html#StyleStrategy-enum, which can be a hint to tell the font not to use a bitmap font. Depending on the fonts available on the system and the font family specified, this may or may not work.
On Windows 2000 fonts are usually not antialiased within a certain range (say sizes 8-16) to make text more crisp and readable.
How can a QModelIndex be retrived from the model for an internal data item?
In order to get a QModelIndex from the model for an internal data item there are 3 options to consider:
- Option 1: Use unique identifiers**
Add a member to each item in the data structure that is used to store a unique identifier for the item. Then reimplement QAbstractItemModel::data() to return that value for a custom item data role that you can specify for your model. Now you can use QAbstractItemModel::match() to retrieve the QModelIndex for your item, using the unique identifier as a search parameter. If you have editable items, you should reimplement setData() as well.
Please see the following web pages for more information:
http://doc.qt.io/qt-5/qabstractitemmodel.html#data http://doc.qt.io/qt-5/qabstractitemmodel.html#match http://doc.qt.io/qt-5/qt.html#ItemDataRole-enum http://doc.qt.io/qt-5/qabstractitemmodel.html#setData
- Option 2: Use QPersistentModelIndex**
Create a QPersistentModelIndex for each item you wish to keep track of when you add the item to the model. QPersistentModelIndex can be stored, and it is used to keep a reference to an item that is valid for as long as the item can be accessed by the model. The QPersistentModelIndex can be used as a QModelIndex.
Please see the following web pages for more information:
http://doc.qt.io/qt-5/qpersistentmodelindex.html
- Option 3: Traverse the model from the root item**
Store a pointer to your item's parent, if it has any. Then store pointers to the parent's parent all the way up to the root item. Once you have found the root item, you can start traversing the model, using QAbstractItemModel::index(). For each returned index, compare its internal pointer with the pointer of the ancestor of your item, and if they match, you can repeat the process, calling index() with the newly found model index, in effect dropping down one level in you data structure and getting closer to your item. When the internal pointer of a model index matches that of your item's parent, you call index() one last time with that model index as the argument, and you should get the QModelIndex for your item. Please consider that in a worst case scenario you will traverse the whole data model.
How to avoid subclassing all available styles when wanting to change a small aspect of a widget for all styles
Since Qt 4.6 you can use QProxyStyle: https://doc.qt.io/qt-5/qproxystyle.html
How do I create tooltips in QHeaderView?
It is possible to create tooltips for each header in a model by setting its Qt::ToolTipRole http://doc.qt.io/qt-5/qt.html#ItemDataRole-enum
QStandardItemModel model ;
model.setRowCount(5);
model.setColumnCount(2);
model.setHeaderData ( 1, Qt::Horizontal, QVariant("test"), Qt::ToolTipRole );
model.setHeaderData ( 1, Qt::Horizontal, QVariant("Column 2"), Qt::DisplayRole );
How can I make Designer look for plugins outside qtDirectory\plugins\designer
You can make designer look for plugins elsewhere using the QT_PLUGIN_PATH http://doc.qt.io/qt-5/qcoreapplication.html#libraryPaths environment variable.
Note that your plugins need to be a in a designer subdirectory inside the path that you specify. See also the documentation on building and installing the plugin http://doc.qt.io/qt-5/designer-creating-custom-widgets.html#building-and-installing-the-plugin.
How can I change the width of the popup list in my combobox?
In order to change the width of the combobox's view, you can subclass QComboBox http://doc.qt.io/qt-5/qcombobox.html and reimplement showPopup() http://doc.qt.io/qt-5/qcombobox.html#showPopup to set the width you want on the view.
See the following example for an indication of how to do this:
#include <QApplication>
#include <QComboBox>
#include <QAbstractItemView>
class ComboBox : public QComboBox
{
public:
ComboBox();
void showPopup();
};
ComboBox::ComboBox() : QComboBox()
{
addItem("one");
addItem("some more text");
}
void ComboBox::showPopup()
{
view()->setFixedWidth(400);
QComboBox::showPopup();
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
ComboBox box;
box.show();
return app.exec();
}
How can I have both text and a pixmap on a QLabel?
This is not possible to achieve with the QLabel http://doc.qt.io/qt-5/qlabel.html API directly, but you can use richtext to make this work. See the following example:
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QLabel label;
label.setText("<img src="fileopen.xpm"> labeltext");
label.show();
return app.exec();
How can I avoid a paintEvent() when focus changes on Windows ?
The trick is to block activate/inactive events. See the example below for a demonstration. Note that it is necessary to set the WA_OpaquePaintEvent http://doc.qt.io/qt-5/qt.html#WidgetAttribute-enum attribute since widgets are defined to be transparent by default. This has been done to allow widgets to have features like antialiased round edges and sub widget transparency. A transparent widget needs to be updated when its parent is updated because an update in the parent will effect the child widget as well. This also applies to palette changes.
By setting the WA_OpaquePaintEvent the widget is no longer transparent and no longer subject to updates as a result of changes in the parent chain.
#include <QtWidgets>
#include <stdio.h>
class cDrawWindow : public QWidget
{
public:
cDrawWindow(QWidget *Parent) : QWidget(Parent)
{
setAttribute(Qt::WA_OpaquePaintEvent);
}
void paintEvent(QPaintEvent *pe)
{
fprintf(stderr, "paintEvent ");
}
bool event(QEvent *e)
{
switch (e->type())
{
case QEvent::WindowActivate:
case QEvent::WindowDeactivate:
return true;
}
return QWidget::event(e);
}
};
class cMainWindow : public QMainWindow
{
private:
cDrawWindow *w;
public:
cMainWindow(void) {
w = new cDrawWindow(this);
setCentralWidget(w);
move(0, 0); }
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
cMainWindow mw;
mw.show();
return a.exec();
}
I have problems building an application that uses a Qt Designer plugin on Windows. Can you give some advice?
First of all, you need to export your class so that it can be used by the plugin, e.g:
class QDESIGNER_WIDGET_EXPORT button : public QPushButton
Also, make sure you have the Q_OBJECT macro in your class declaration, if you do not include it then the plugin will not have access to the correct QMetaObject which would have information about the class itself. As a result this would break the introspection of the plugin.
In the .pro file of your plugin you also need to give some extra information
TEMPLATE = lib
Make sure you specify the lib template since you are building a library.
DESTDIR = $$[QT_INSTALL_PLUGINS]/designer
In addition you need to specify where the plugin should be located. Qt will look in plugins/designer by default, so this is where your plugin should be.
An example .pro file may like look this:
TEMPLATE = lib
CONFIG+= designer plugin debug_and_release
LANGUAGE = C++
TARGET = buttonPlugin
SOURCES += buttonPlugin.cpp button.cpp
HEADERS += buttonPlugin.h button.h
DESTDIR = $$[QT_INSTALL_PLUGINS]/designer
CONFIG += qt warn_on release plugin
With your application you need to add the following to your application's .pro file:
LIBS+=$$[QT_INSTALL_PLUGINS]/designer/nameOfYourPlugin.lib
This line is necessary to link against the lib file and at runtime the application will use the dll. The lib file is located at $$[QT_INSTALL_PLUGINS]/designer since this is what was specified as the DESTDIR in the plugin's pro file.
INCLUDEPATH += text/example/yourPluginDir/yourWidget
You also need to specify the INCLUDEPATH, so that your application will be able to find your custom widget's header file.
An example .pro file can look as follows:
TEMPLATE = app
LANGUAGE = C++
LIBS += $$[QT_INSTALL_PLUGINS]/designer/buttonPlugin.lib
INCLUDEPATH += text/example/yourPluginDir/yourWidget
CONFIG += qt warn_on release
SOURCES += main.cpp
FORMS = form1.ui
Finally, your application also needs to be able to find the plugin's dll. This can be done either by putting the myPlugin.dll into the same directory as your application, or by adding the path to the myPlugin.dll to the PATH environment variable.
How can I create checkable items in a QTreeWidget?
In order to create checkable items in a QTreeWidget http://doc.qt.io/qt-5/qtreewidget.html, you need to pass in the Qt::ItemIsUserCheckable http://doc.qt.io/qt-5/qt.html#ItemFlag-enum flag to QTreeWidgetItem::setFlags() http://doc.qt.io/qt-5/qtreewidgetitem.html#setFlags in addition to calling QTreeWidgetItem::setCheckState() http://doc.qt.io/qt-5/qtreewidgetitem.html#setCheckState. See the following example for a demonstration:
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QTreeWidget tree(0);
tree.setColumnCount(1);
QTreeWidgetItem *itemOne = new QTreeWidgetItem(&tree);
itemOne->setFlags(itemOne->flags()|Qt::ItemIsUserCheckable);
itemOne->setText(0,"Item one");
itemOne->setCheckState(0, Qt::Checked);
tree.show();
return app.exec();
}
How can I avoid drawing the focus rect on my buttons?
In order to not draw the focus rect of the buttons it is necessary to subclass the style and reimplement QStyle::drawControl() http://doc.qt.io/qt-5/qstyle.html#drawControl to strip out the State_HasFocus http://doc.qt.io/qt-5/qstyle.html#StateFlag-enum state for the buttons.
See the following example:
#include <QtWidgets>
class Style : public QWindowsStyle
{
public:
Style() {}
void drawControl(ControlElement element, const QStyleOption *option,
QPainter *painter, const QWidget *widget = nullptr) const
{
if (element == QStyle::CE_PushButton) {
const QStyleOptionButton *b = qstyleoption_cast<const QStyleOptionButton *>(option);
QStyleOptionButton *btn = (QStyleOptionButton *)b;
if (btn) {
if (btn->state & State_HasFocus) {
btn->state = btn->state ^ State_HasFocus;
}
}
QWindowsStyle::drawControl(element, btn, painter, widget);
} else {
QWindowsStyle::drawControl(element, option, painter, widget);
}}};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QWidget box;
QPushButton *button1 = new QPushButton(&box);
button1->setText("Number one");
QPushButton *button2 = new QPushButton(&box);
button2->setText("Number two");
button1->setStyle(new Style());
button2->setStyle(new Style());
QVBoxLayout *layout = new QVBoxLayout(&box);
layout->addWidget(button1);
layout->addWidget(button2);
box.show();
return app.exec();
}
When the FileMode is DirectoryOnly in my QFileDialog, how can I select multiple directories?
By default it is only possible to select one directory when the FileMode http://doc.qt.io/qt-5/qfiledialog.html#FileMode-enum is DirectoryOnly. You can change this by getting hold of the QListView http://doc.qt.io/qt-5/qlistview.html and QTreeView http://doc.qt.io/qt-5/qtreeview.html children of the QFileDialog http://doc.qt.io/qt-5/qfiledialog.html and setting their selection mode to MultiSelection http://doc.qt.io/qt-5/qabstractitemview.html#SelectionMode-enum.
See the following example:
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication a(argc, argv);
QFileDialog w;
w.setFileMode(QFileDialog::DirectoryOnly);
QListView *l = w.findChild<QListView*>("listView");
if (l) {
l->setSelectionMode(QAbstractItemView::MultiSelection);
}
QTreeView *t = w.findChild<QTreeView*>();
if (t) {
t->setSelectionMode(QAbstractItemView::MultiSelection);
}
w.exec();
}
When converting my pixmap to a HBITMAP using toWinHBITMAP(QPixmap::PremultipliedAlpha ) , they appear with a black background. How can I give the icons a transparent background?
You need to use the GDI function AlphaBlend which supports proper alpha. When asking for PremultipledAlpha, you need to use AlphaBlend.
The following example demonstrates how this can be done:
#include <QtWidgets>
#include <qt_windows.h>
void drawHBITMAP(HDC dc, int x, int y, int w, int h, HBITMAP hbm)
{
HDC bmdc = CreateCompatibleDC(dc);
HGDIOBJ oldbm = SelectObject(bmdc, hbm);
BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
AlphaBlend(dc, x, y, w, h, bmdc, 0, 0, w, h, blend);
SelectObject(bmdc, oldbm);
DeleteDC(bmdc);
}
int main(int argc, char** argv)
{
QApplication app(argc, argv);
HBITMAP image1;
QPixmap pix1( "somePixmap" );
pix1.setMask( pix1.createHeuristicMask() );
image1 = pix1.toWinHBITMAP(QPixmap::PremultipliedAlpha );
HDC dc = GetDC(0);
drawHBITMAP(dc, 100, 100, pix1.width(), pix1.height(), image1);
}
Note that you need to link against msimg32.dll.
How to compress data with Qt?
Qt uses the zlib library to provide compression. This means that you can compress and decompress your bytearrays of data using Qt. See the documentation on qUncompress() http://doc.qt.io/qt-5/qbytearray.html#qUncompress
Note that this does not produce file archives that can be opened by other applications, to do that you will need to write it yourself using Qt's custom file handling system http://doc.qt.io/qt-4.8/qabstractfileengine.html#details or use a 3rd party library.
How can I prevent the MDI subwindows from closing when pressing Ctrl+W?
You can stop the Ctrl+W shortcut from triggering by reimplementing the eventFilter() http://doc.qt.io/qt-5/qobject.html#eventFilter for your QMainWindow http://doc.qt.io/qt-5/qmainwindow.html and returning true when the shortcut is Ctrl+W.
The event filter can be installed on the subwindows or on the application itself. Note that installing the event filter on the application will require more resources.
The example below illustrates how this can be done:
#include <QtWidgets>
class Object : public QObject
{
Q_OBJECT
public:
Object(QWidget *parent) : QObject(parent)
{}
bool eventFilter(QObject *obj, QEvent *event){
if (event->type() == QEvent::ShortcutOverride) {
QKeyEvent *ev = static_cast<QKeyEvent *>(event);
if (ev->modifiers() == Qt::CTRL && ev->key() == Qt::Key_W) {
QMessageBox::information(0,"shortcut notification", "You pressed Ctrl+W");
//stop the event
return true;
}
}
// standard event processing
return QObject::eventFilter(obj, event);
}
};
#include "main.moc"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QMainWindow window;
QMdiArea *area = new QMdiArea(&window);
QMdiSubWindow *first = area->addSubWindow(new QLineEdit(area));
QMdiSubWindow *second = area->addSubWindow(new QLineEdit(area));
window.setCentralWidget(area);
Object *object = new Object(&window);
first->installEventFilter(object);
second->installEventFilter(object);
window.show();
return app.exec();
}
Compiling a Qt program fails with error messages looking something like this: undefined reference to `_vt.11QPushButton'
This usually means you have two different versions of the Qt library (libqt.so) installed on your system, and they interfere with each other. Either modify the compiler's library search path so that it finds your new Qt library first, or simply remove the old one.
It may also indicate that your Qt library was compiled with a compiler that is incompatible with the one you are using, e.g. gcc vs. egcs.
If you get this error trying to run a pre-compiled Qt program, it usually means that the program has been compiled with a version of Qt that is newer than the one on your system. Upgrade to the latest version of Qt.
Polling SQL connection to test connectivity.
There is currently a suggestion to add this feature as the one function that should serve this purpose doesn't currently do it.
http://bugreports.qt.io/browse/QTBUG-223
There isn't actually a signal or any other indicator to poll the status of a connection in this case. The workaround for this is to send a query that you know will always be returned true, and if it returns false, you will know that the connection is down.
QWebView does not display Chinese fonts from a Chinese web site
On X11 this problem can be solved by installing libFreetype and libFontconfig. These libraries are needed to render the true type fonts that contain these characters. On Windows you need to install the Chinese fonts from the Windows installation CD to get this to work.
How can I use QSound with ALSA ?
There is no ALSA support for QSound as ALSA only works in Linux. Qt uses its own sound server(QSS) that interacts with /dev/dsp directly. If you want to use ALSA on Linux, then implement it directly with the ALSA API or use Phonon.
Is there a Qt way to handle UNIX/POSIX signals?
There isn't a true Qt way because of the non-crossplatform nature of UNIX/POSIX signals, but you should be able to do it using QSocketNotifier. You can read more about this here:
http://doc.qt.io/qt-5/unix-signals.html
How can I move a window around when using Qt::FramelessWindowHint?
You need to reimplement the mouse event handlers for the widgets you would like be able to move your window with. Here is an example using QMenuBar http://doc.qt.io/qt-5/qmenubar.html:
#ifndef CMENUBAR_H
#define CMENUBAR_H
#include <QMenuBar>
class QPoint;
class QMouseEvent;
class QWidget;
class CMenuBar : public QMenuBar
{
public:
CMenuBar();
CMenuBar(QWidget *par);
protected:
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
private:
QPoint offset;
bool moving;
};
#endif // CMENUBAR_H
#include "cmenubar.h"
#include <QPoint>
#include <QMouseEvent>
#include <QDebug>
CMenuBar::CMenuBar()
{
moving = false;
}
CMenuBar::CMenuBar(QWidget *par)
{
setParent(par);
moving = false;
setMouseTracking(false);
}
void CMenuBar::mousePressEvent(QMouseEvent *event)
{
QMenuBar::mousePressEvent(event);
if((event->button() == Qt::LeftButton) && !actionAt(event->pos())) {
moving = true;
offset = event->pos();
}
}
void CMenuBar::mouseMoveEvent(QMouseEvent *event)
{
QMenuBar::mouseMoveEvent(event);
if(moving)
parentWidget()->move(event->globalPos() - offset);
}
void CMenuBar::mouseReleaseEvent(QMouseEvent *event)
{
QMenuBar::mouseReleaseEvent(event);
if(event->button() == Qt::LeftButton) {
moving = false;
}
}
Antialiasing does not work with VNC
This is most likely due to lack of XRender support in the VNC Client. To get antialiasing to work you must either enable XRender support on the VNC Client, or use the raster paint engine. This can be done by starting the application with ./myApp -graphicssystem raster
On which operating systems does Qt Creator run?
Due to the nature of Qt, Qt Creator should eventually run on every platform supported by Qt. You can find an overview of the supported platforms here:
Supported platforms http://doc.qt.io/qt-5/qtcreator-2.1/creator-os-supported-platforms.html
A shared Qt library makes it necessary to distribute the Qt DLL together with your software. Applications and libraries linked against a shared Qt library are small and can make use of components and plugins. All applications created with a static library will be at least 1.5MB in size and it is not possible to build or use any components or plugins with a static Qt library.
Moving my application away from MFC, why would I select Qt as the toolkit to move to?
The features of Qt in general are presented on the main product page. For moving an existing MFC application, the following facts are particularly relevant:
- Qt is actively maintained and developed.
- Qt lets you target multiple platforms (Linux, Unix, Windows, Mac) with a single source code base.
- Qt is commercially developed and commercial support, training and consultancy services are provided.
- The Qt API has an intuitive, logical design that makes it easy to learn and efficient to use.
- Qt is a C++ toolkit, just like MFC. This means that the porting job will be much simpler, and allow for a much higher degree of code reuse, than than if porting to e.g. Java or .NET/C#.
- Through the Qt/MFC Migration Framework, MFC applications can be partly and gradually ported to Qt. It is not necessary to do the entire port in one go.
- Qt provides a consistent class API that covers both GUI and all the operating system functionality needed by most applications.
How can I prevent the clicked() signal from being emitted when I want to grab the doubleClicked() signal in my item view ?
Normally the clicked() signal will be emitted in addition to the doubleClicked() signal since you are actually clicking on the widget. The same happens with events when you double click on a widget, you get a press event, release event then a double click event. The press followed by the release indicates that a click occurred. If you don't want this behavior then you can start a timer in the mouseReleaseEvent() http://doc.qt.io/qt-5/qabstractitemview.html#mouseReleaseEvent and then in the mouseDoubleClickEvent() http://doc.qt.io/qt-5/qabstractitemview.html#mouseDoubleClickEvent kill the timer. If the timer times out, you can emit the clicked signal and stop the timer.
See the following example for an illustration:
#include <QtWidgets>
class TableWidget : public QTableWidget
{
Q_OBJECT
public:
TableWidget()
{
ignoreNextRelease = false;
timer = new QTimer(this);
setColumnCount(3);
setRowCount(3);
connect(this, SIGNAL(cellClicked (int, int)), this, SLOT(testSlot()));
connect(this, SIGNAL(cellDoubleClicked (int, int)), this, SLOT(testSlot2()));
connect(timer, SIGNAL(timeout()), this, SLOT(emitClicked()));
}
void mouseReleaseEvent(QMouseEvent *event)
{
if (!ignoreNextRelease) {
timer->start(QApplication::doubleClickInterval());
blockSignals(true);
QTableWidget::mouseReleaseEvent(event);
blockSignals(false);
}
ignoreNextRelease = false;
}
void mouseDoubleClickEvent(QMouseEvent *event)
{
ignoreNextRelease = true;
timer->stop();
QTableWidget::mouseDoubleClickEvent(event);
}
public slots:
void testSlot()
{
qDebug("cellClicked() was emitted");
}
void testSlot2()
{
qDebug("cellDoubleClicked was emitted");
}
void emitClicked()
{
emit cellClicked(currentRow(), currentColumn());
timer->stop();
}
private:
QTimer *timer;
bool ignoreNextRelease;
};
#include "main.moc"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
TableWidget box;
box.show();
return app.exec();
}
How can I draw custom subcontrols for a complex control ?
You can achieve this either by subclassing the style or by using a stylesheet http://doc.qt.io/qt-5/stylesheet.html. If you want to style the drop-down button of a combobox for example, then you can subclass the style and reimplement drawComplexControl() http://doc.qt.io/qt-5/qstyle.html#drawComplexControl to remove the existing button. Then after the style has done its painting, you can do your custom painting. See the following example:
#include <QtWidgets>
class Style : public QWindowsStyle
{
public:
Style() {}
void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = nullptr) const override
{
if (const QStyleOptionComboBox *group = qstyleoption_cast<const QStyleOptionComboBox*>(option)) {
QStyleOptionComboBox newComboBox(*group);
newComboBox.subControls &= ~QStyle::SC_ComboBoxArrow;
// Let the style do its drawing
QWindowsStyle::drawComplexControl(control, &newComboBox, painter, widget);
// Do your own drawing
QRect rect= subControlRect(control, option,SC_ComboBoxArrow, widget);
QPixmap pix = standardPixmap(QStyle::SP_TitleBarMenuButton, option, widget);
painter->save();
painter->setBrushOrigin(rect.topLeft());
painter->fillRect(rect, QBrush(pix));
painter->restore();
} else {
QWindowsStyle::drawComplexControl(control, option, painter, widget);
}}};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QWidget widget;
QVBoxLayout *layout = new QVBoxLayout(&widget);
QComboBox *box = new QComboBox(&widget);
box->insertItem(0,"one");
box->setStyle(new Style());
layout->addWidget(box);
widget.show();
return app.exec();
}
Other parts of the combobox can be modified by accessing the properties of the QStyleOptionComplex pointer passed in to drawComplexControl in the example above.
When using style sheets, then the drop-down button can be styled using the
- drop-down sub-control and the arrow mark inside the drop-down button can be
styled using the ::down-arrow sub-control.See the documentation:
http://doc.trolltech.com/stylesheet.html#list-of-stylable-widgets
To see how this works, you can run the stylesheet example under yourQtVersion\examples\widgets\stylesheet and open the editor under File/Edit Style to see how the combobox is styled there.
How can I change the header text of my model based view?
In order to change the header text of a model based view you need to reimplement headerData() http://doc.qt.io/qt-5/qabstractitemmodel.html#headerData and return the text you want for the relevant section, orientation and row there.
#include <QtWidgets>
class Model : public QAbstractTableModel {
public:
Model(QObject *parent)
{
QStringList firstRow;
QStringList secondRow;
for (int i = 0; i < 5; i++ ) {
firstRow.insert(i,"Row 1 " + QString::number(i+1));
secondRow.insert(i,"Row 2 " + QString::number(i+1));
}
stringList << firstRow << secondRow;
}
// Returns the number of rows
int rowCount ( const QModelIndex & parent = QModelIndex() ) const
{
return stringList.count();
}
// Returns the number of columns
int columnCount ( const QModelIndex & parent = QModelIndex() ) const
{
return stringList[0].count();
}
// Returns an appropriate value for the requested section, orientation and role
QVariant headerData ( int section, Qt::Orientation orientation, int role) const
{
if (role ==Qt::DisplayRole ) {
if (section == 0 && orientation == Qt::Vertical ) {
return QString("First");
} else if (section == 1 && orientation == Qt::Vertical ) {
return QString("Second");
} else {
return QVariant();
}} else {
return QVariant();
}
}
// Returns an appropriate value for the requested data.
// If the view requests an invalid index or if the role is not
// Qt::DisplayRole, an invalid variant is returned.
// Any valid index that corresponds to a string for the index'scolumn and row in
// the stringlist is returned
QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const
{
if (!index.isValid())
return QVariant();
if (role != Qt::DisplayRole)
return QVariant();
QStringList list = (QStringList)stringList.at(index.row());
return list.at(index.column());
}
private:
QList<QStringList>stringList;
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QWidget widget;
QHBoxLayout *layout = new QHBoxLayout(&widget);
QTableView *tableView = new QTableView(&widget);
Model *model = new Model(tableView);
tableView->setModel(model);
layout->addWidget(tableView);
widget.show();
return app.exec();
}
How can I create a dialog that can be closed programatically, but not by the user ?
You can achieve this by reimplementing closeEvent() http://doc.qt.io/qt-5/qwidget.html#closeEvent and then ignoring or accepting the event depending on a flag.
The following is an example of how to do this:
#include <QtWidgets>
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog();
void closeEvent ( QCloseEvent * e );
public slots:
void closeDialog();
private:
bool ignoreCloseEvent;
};
Dialog::Dialog() : QDialog()
{
ignoreCloseEvent = true;
}
void Dialog::closeEvent ( QCloseEvent * e )
{
if (!ignoreCloseEvent) {
QDialog::closeEvent(e);
} else {
e->ignore();
}
}
void Dialog::closeDialog()
{
ignoreCloseEvent = false;
accept();
}
#include "main.moc"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
Dialog dialog;
dialog.show();
return app.exec();
}
Is it possible for either the left or right dock areas to have full height of their side rather than having the bottom take the full width?
It is possible to get what you are looking for, but you have to be kind of sneaky about it. The real trick is to have a QMainWindow http://doc.qt.io/qt-5/qmainwindow.html as the central widget of your QMainWindow and then dock bottom QDockWidget http://doc.qt.io/qt-5/qdockwidget.html in there. Then you can disable the the bottom dock area for your toplevel QMainWindow and dock the left and right dock windows there. We do this trick with Linguist to get a very similar look, so you can check out Linguist http://doc.qt.io/qt-5/linguist-manual.html to see how it works there.
The example below is a demonstration of how this can be done.
#include <QtWidgets>
class MainWindow : public QMainWindow
{
public:
MainWindow(QWidget *parent = nullptr) : QMainWindow(parent)
{
QMainWindow *window = new QMainWindow(this);
window->setCentralWidget(new QTextEdit(window));
window->setWindowFlags(Qt::Widget);
setCentralWidget(window);
QDockWidget *dw = new QDockWidget(window);
dw->setWidget(new QTextEdit(dw));
window->addDockWidget(Qt::BottomDockWidgetArea, dw);
QDockWidget *dockMain = new QDockWidget(this);
dockMain->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
addDockWidget(Qt::LeftDockWidgetArea, dockMain);
addDockWidget(Qt::RightDockWidgetArea, new QDockWidget(this));
dockMain->setWidget(new QLabel("The left dock area", dockMain));
}};
int main(int argc, char **argv)
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
QScriptEngine::uncaughtExceptionNumber() is returning 0 even though the error is elsewhere. What's wrong?
The cause of the problem probably is QScriptValue::toString() http://doc.qt.io/qt-5/qscriptvalue.html#toString is being called on the QScriptValue returned from the evaluate() http://doc.qt.io/qt-5/qscriptengine.html#evaluate call before uncaughtExceptionNumber() is called. When QScriptValue::toString() http://doc.qt.io/qt-5/qscriptvalue.html#toString is called it will reset the exception number in the QScriptEngine http://doc.qt.io/qt-5/qscriptengine.html since it is ready for a new evaluate(). So code like:
QScriptValue val = engine->evaluate(code);
if (val.isError()) {
qDebug() << val.toString();
qDebug() << engine->uncaughtExceptionNumber();
}
Should be changed to:
QScriptValue val = engine->evaluate(code);
if (val.isError()) {
qDebug() << engine->uncaughtExceptionNumber();
qDebug() << val.toString();
}
So that the uncaughtExceptionNumber() is obtained before toString() is called.
Unloading the plugin causes Qt to clear the menubar. You can disable Qt's interaction with the native menubar by calling qt_mac_set_native_menubar() http://doc.qt.io/qt-5/exportedfunctions.html#void-qt-mac-set-native-menubar-bool-enable
In general, most plugins in a non-Qt application don't need to interact with the menubar anyway.
Is Qt compatible with .NET?
Yes. You can use Qt to create .NET-compatible applications. For details on how to do this, please refer to Using Qt objects in Microsoft .NET in the documentation http://doc.qt.io/qt-5/activeqt.html.
Does Qt Creator support embedded/mobile software development?
Yes, Qt Creator can be used for developing for any platform that is supported by Qt.
Which image formats does Qt support?
Qt currently supports the following image file formats: PNG, BMP, XBM, XPM and PNM. It may also support JPEG and GIF, if specially configured during compilation. The different PNM formats are: PBM (P1 or P4), PGM (P2 or P5), and PPM (P3 or P6). In Qt 4.1 we will also support SVG which provides SVG 1.2 Tiny support.
Why does nothing happen when I set the palette background color on a QPushButton in some styles?
There are two different type of styles in Qt, one type just uses colors to indicate the background, foreground etc and the other type is a pixmap based one which usually rely on a theming engine on the underlying platform. When the style is a pixmap based one then simply changing the palette will usually not result in a visual change on that widget. Currently, there are three pixmap based styles, these being Windows XP, Windows Vista and Mac.
These styles use the platform's theming engine to draw most of the parts of the widgets. The engine uses pixmaps to define its look. Setting the color of a role in the Qt palette therefore will not always result in changes to the looks of the widget, since this new color will not change the pixmap defined in the theming engine. (Other things like font color of course will work as usual). See:
http://doc.qt.io/qt-5/qq/qq09-q-and-a.html#winxp
You have several options:
1. **Go with the flow**
Just accept the style. Easy, and gives your UI a consistent look.
2. **Set the style of that one widget to something like Windows Style**
Of course, that will make the widget look very different from all the others, since they won't have the same visual style (e.g. other types of borders etc).
3. **Use QProxyStyle**
Check out http://doc.qt.io/qt-5/qproxystyle.html
4. **Use Stylesheets instead**
Using stylesheets will enable you to change just part of the look and feel of a widget and still keep the native look and feel for other widgets. It will preserve what it can about the widget being styled and enable it to be changed easily.
See http://doc.qt.io/qt-5/stylesheet.html for more information
How can I change the size of the icon in the tab of a QToolBox?
The easiest way is probably by setting a stylesheet http://doc.qt.io/qt-5/stylesheet.html on the QToolBox as follows:
toolbox.setStyleSheet("icon-size: aNumberpx");
You can also achieve it by subclassing the style and setting the value of pixelMetric() http://doc.qt.io/qt-5/qstyle.html#pixelMetric to what you want when the metric is QStyle::PM_SmallIconSize and the widget inherits QToolBox. The example below illustrates both ways.
#include <QtWidgets>
class Style : public QWindowsStyle
{
public:
Style() {}
int pixelMetric (PixelMetric metric, const QStyleOption * option = nullptr, const QWidget * widget = nullptr) const override
{
if (metric == QStyle::PM_SmallIconSize && widget->inherits("QToolBox")) {
return 50;
}
return QWindowsStyle::pixelMetric(metric, option, widget);
}
};
class ToolBox : public QToolBox
{
public:
ToolBox()
{
QPixmap pix(50, 50);
pix.fill(Qt::red);
addItem(new QLineEdit(this), QIcon(pix), "QLineEdit");
addItem(new QPushButton("Click me", this), "QPushButton");
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
ToolBox box;
#if 0
app.setStyle(new Style());
#else
box.setStyleSheet("icon-size: 50px");
#endif
box.show();
return app.exec();
}
Is there a way to tell QTreeView to always resize itself based on the contents of all columns?
To make a QTreeView always resize itself based on the contents of all columns, you can connect to the dataChanged() http://doc.qt.io/qt-5/qabstractitemmodel.html#dataChanged signal and call resizeColumnToContents() http://doc.qt.io/qt-5/qtreeview.html#resizeColumnToContents when the data changes.
See the following example for an illustration:
#include <QtWidgets>
class TreeView :public QTreeView
{
Q_OBJECT
public:
TreeView();
public slots:
void adaptColumns(const QModelIndex &topleft,
const QModelIndex &bottomRight);
private:
QStandardItemModel *model;
};
TreeView::TreeView() : QTreeView()
{
// Create a generic model for storing custom data
model = new QStandardItemModel();
// Prepend 4 rows into the model
model->insertRows(0, 4);
// Prepend 4 columns into the model
model->insertColumns(0, 4);
for (int row = 0; row < 4; row++) {
for (int col = 0; col < 4; col++) {
// Return a model index for the given row and column.
QModelIndex index = model->index(row, col);
// Set the index's data to the specified value
model->setData(index, QVariant((row+1) * (col+1)).toString());
}
}
setModel(model);
connect(model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex& ) ),
this, SLOT(adaptColumns(const QModelIndex &, const QModelIndex&) ) );
}
void TreeView::adaptColumns (const QModelIndex & topleft, const QModelIndex& bottomRight)
{
int firstColumn= topleft.column();
int lastColumn = bottomRight.column();
// Resize the column to the size of its contents
do {
resizeColumnToContents(firstColumn);
firstColumn++;
} while (firstColumn < lastColumn);
}
#include "main.moc"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
TreeView view;
view.show();
return app.exec();
}
How can I make the scrollbar thinner ?
The scrollbar will not be thinner than the QApplication::globalStrut() http://doc.qt.io/qt-5/qapplication.html#globalStrut-prop so you can use this to make sure it has a certain minimum size.
Another approach that also can make it thinner than the default is to subclass the style and reimplement pixelMetric() http://doc.qt.io/qt-5/qstyle.html#pixelMetric
int pixelMetric(PixelMetric metric, const QWidget *widget = nullptr) const
{
if (metric == QStyle::PM_ScrollBarExtent)
return 5; // This will make the scrollbar five pixels wide
return style->pixelMetric(metric, widget);
}
How can I detect a period of no user interaction?
What you will need to do is use a QTimer http://doc.qt.io/qt-5/qtimer.html that times out after a number of minutes of no user interaction. Whenever there is user interaction, then you restart the timer. The easiest way to detect any user interaction within an application i.e. mouse clicks(any button), mouse wheel and keystrokes is to install an event filter on the application that listens for these kind of events. For example:
#include <QtWidgets>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget()
{
timer = new QTimer(this);
timer->start(4000);
installEventFilter(this);
connect(timer, SIGNAL(timeout()), this, SLOT(testSlot()));
}
bool eventFilter(QObject *o, QEvent *evt)
{
switch(evt->type()) {
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::Wheel:
case QEvent::KeyPress:
case QEvent::KeyRelease:
timer->start(6000);
break;
default:
break;
}
return false;
}
private:
QTimer *timer;
public slots:
void testSlot()
{
qDebug() << No user interaction;
}
};
#include main.moc"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
Widget box;
box.resize(100, 200);
box.show();
return app.exec();
}
How can I change the color of the items in my model?
In order to change the color of the items in the model you need to reimplement the data() http://doc.qt.io/qt-5/qabstractitemmodel.html#data function and return the colors you want for the Qt::BackgroundColorRole or the Qt::TextColorRole roles http://doc.qt.io/qt-5/qt.html#ItemDataRole-enum.
The example below illustrates how this can be achieved.
Note that you can also reimplement QStyledItemDelegate::paint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#paint in order to change the color the items in a view.
#include <QtWidgets>
class ColorModel : public QAbstractTableModel
{
public:
ColorModel(QObject *parent) : QAbstractTableModel(parent)
{
QStringList firstRow;
QStringList secondRow;
for (int i = 0; i < 5; i++ ) {
firstRow.insert(i,"Row " + QString::number(i+1));
secondRow.insert(i,"Row " + QString::number(i+1));
}
stringList << firstRow << secondRow;
}
// Returns the number of rows
int rowCount(const QModelIndex &parent = QModelIndex()) const
{
return 2;
}
// Returns the number of columns
int columnCount(const QModelIndex &parent = QModelIndex()) const
{
return 5;
}
// Returns an appropriate value for the requested data.
// If the view requests an invalid index or if the role is not
// Qt::DisplayRole, Qt::BackgroundColorRole or QTextColorRole, an invalid variant is
// returned.
// Any valid index that corresponds to a string for the index's column and row in
// the stringlist is returned for the Qt::DisplayRole
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
{
if (!index.isValid())
return QVariant();
if (role == Qt::BackgroundRole)
{
if (index.row() == 0)
return QColor(Qt::blue);
else
return QColor(Qt::white);
} else if (role == Qt::DisplayRole) {
QStringList list = (QStringList)stringList.at(index.row());
return list.at(index.column());
} else if (role == Qt::ForegroundRole ) {
if (index.row() == 1)
return QColor(Qt::red);
}
return QVariant();
}
private:
// Each row will consist of a list of strings
QList<QStringList>stringList;
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QWidget widget;
QHBoxLayout *layout = new QHBoxLayout(&widget);
QTreeView *treeView = new QTreeView(&widget);
QTableView *tableView = new QTableView(&widget);
ColorModel *model = new ColorModel(tableView);
tableView->setModel(model);
treeView->setModel(model);
layout->addWidget(treeView);
layout->addWidget(tableView);
widget.show();
return app.exec();
}
How can I handle events in the titlebar and change its color etc ?
The titlebar belongs to the OS and we don't have control over that one. You can create your own titlebar, but note that this requires some work. In order to create your own titlebar then make a QWidget http://doc.qt.io/qt-5/qwidget.html subclass that contains three toolbuttons that handle the close, minimize and maximize events in addition to the moving of the window.
Then make a QFrame http://doc.qt.io/qt-5/qframe.html subclass which does not have a titlebar provided via the window system. This is done by setting the Qt::FramelessWindowHint http://doc.qt.io/qt-5/qt.html#WindowType-enum window flag, however this will make it impossible to resize or move the window via the window system. What can be done is you can add your custom titlbar as a private member to the frame and add the it first to the frame's vertical layout. The frame also needs a content widget which allows widgets to be added to it. Finally the QFrame subclass needs to reimplement the mouse events to handle the resizing and moving of the window.
The example below demonstrates how this can be achieved.
#include <QtWidgets>
class TitleBar : public QWidget
{
Q_OBJECT
public:
TitleBar(QWidget *parent)
{
// Don't let this widget inherit the parent's backround color
setAutoFillBackground(true);
// Use a brush with a Highlight color role to render the background
setBackgroundRole(QPalette::Highlight);
minimize = new QToolButton(this);
maximize = new QToolButton(this);
close= new QToolButton(this);
// Use the style to set the button pixmaps
QPixmap pix = style()->standardPixmap(QStyle::SP_TitleBarCloseButton);
close->setIcon(pix);
maxPix = style()->standardPixmap(QStyle::SP_TitleBarMaxButton);
maximize->setIcon(maxPix);
pix = style()->standardPixmap(QStyle::SP_TitleBarMinButton);
minimize->setIcon(pix);
restorePix = style()->standardPixmap(QStyle::SP_TitleBarNormalButton);
minimize->setMinimumHeight(20);
close->setMinimumHeight(20);
maximize->setMinimumHeight(20);
QLabel *label = new QLabel(this);
label->setText("Window Title");
parent->setWindowTitle("Window Title");
QHBoxLayout *hbox = new QHBoxLayout(this);
hbox->addWidget(label);
hbox->addWidget(minimize);
hbox->addWidget(maximize);
hbox->addWidget(close);
hbox->insertStretch(1, 500);
hbox->setSpacing(0);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
maxNormal = false;
connect(close, SIGNAL( clicked() ), parent, SLOT(close() ) );
connect(minimize, SIGNAL( clicked() ), this, SLOT(showSmall() ) );
connect(maximize, SIGNAL( clicked() ), this, SLOT(showMaxRestore() ) );
}
public slots:
void showSmall()
{
parentWidget()->showMinimized();
}
void showMaxRestore()
{
if (maxNormal) {
parentWidget()->showNormal();
maxNormal = !maxNormal;
maximize->setIcon(maxPix);
} else {
parentWidget()->showMaximized();
maxNormal = !maxNormal;
maximize->setIcon(restorePix);
}
}
protected:
void mousePressEvent(QMouseEvent *me)
{
startPos = me->globalPos();
clickPos = mapToParent(me->pos());
}
void mouseMoveEvent(QMouseEvent *me)
{
if (maxNormal)
return;
parentWidget()->move(me->globalPos() - clickPos);
}
private:
QToolButton *minimize;
QToolButton *maximize;
QToolButton *close;
QPixmap restorePix, maxPix;
bool maxNormal;
QPoint startPos;
QPoint clickPos;
};
class Frame : public QFrame
{
public:
Frame()
{
m_mouse_down = false;
setFrameShape(Panel);
// Make this a borderless window which can't
// be resized or moved via the window system
setWindowFlags(Qt::FramelessWindowHint);
setMouseTracking(true);
m_titleBar = new TitleBar(this);
m_content = new QWidget(this);
QVBoxLayout *vbox = new QVBoxLayout(this);
vbox->addWidget(m_titleBar);
vbox->setMargin(0);
vbox->setSpacing(0);
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(m_content);
layout->setMargin(5);
layout->setSpacing(0);
vbox->addLayout(layout);
}
// Allows you to access the content area of the frame
// where widgets and layouts can be added
QWidget *contentWidget() const { return m_content; }
TitleBar *titleBar() const { return m_titleBar; }
void mousePressEvent(QMouseEvent *e)
{
m_old_pos = e->pos();
m_mouse_down = e->button() == Qt::LeftButton;
}
void mouseMoveEvent(QMouseEvent *e)
{
int x = e->x();
int y = e->y();
if (m_mouse_down) {
int dx = x - m_old_pos.x();
int dy = y - m_old_pos.y();
QRect g = geometry();
if (left)
g.setLeft(g.left() + dx);
if (right)
g.setRight(g.right() + dx);
if (bottom)
g.setBottom(g.bottom() + dy);
setGeometry(g);
m_old_pos = QPoint(!left ? e->x() : m_old_pos.x(), e->y());
} else {
QRect r = rect();
left = qAbs(x - r.left()) <= 5;
right = qAbs(x - r.right()) <= 5;
bottom = qAbs(y - r.bottom()) <= 5;
bool hor = left | right;
if (hor && bottom) {
if (left)
setCursor(Qt::SizeBDiagCursor);
else
setCursor(Qt::SizeFDiagCursor);
} else if (hor) {
setCursor(Qt::SizeHorCursor);
} else if (bottom) {
setCursor(Qt::SizeVerCursor);
} else {
setCursor(Qt::ArrowCursor);
}
}
}
void mouseReleaseEvent(QMouseEvent *e)
{
m_mouse_down = false;
}
private:
TitleBar *m_titleBar;
QWidget *m_content;
QPoint m_old_pos;
bool m_mouse_down;
bool left, right, bottom;
};
#include "main.moc"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
Frame box;
box.move(0,0);
QVBoxLayout *l = new QVBoxLayout(box.contentWidget());
l->setMargin(0);
QTextEdit *edit = new QTextEdit(box.contentWidget());
l->addWidget(edit);
box.show();
return app.exec();
}
Note that some strange behavior may be seen when resizing the window really small horizonally to the right on Windows (the window will start moving instead of resizing). This is due to limitations on Windows and there is nothing we can do about this unfortunately.
How can I specify a default location and file name that will be used if a user selects print to file, but not have print to file as the default option ?
When calling setOutputFileName() http://doc.qt.io/qt-5/qprinter.html#setOutputFileName you can specify the default output directory for the file, but this will also cause QPrinter http://doc.qt.io/qt-5/qprinter.html to print to the file specified. If you want to specify an output directory for the file and at the same time have printing to a real printer as the default option, then this is possible to achieve. To do so you need to create a QPrintDialog http://doc.qt.io/qt-5/qprintdialog.html and if the user choose print to file the print dialog will set the output file name to a non-empty string. The programmer can then choose to look at the file name after the print dialog has been executed and pop up a filedialog or similar to specify the full path for the name.
Why are the changes made in the Language tab in the International settings not respected on the Mac?
At the moment it is not possible to detect what language is set in the International->Language tab using QLocale http://doc.qt.io/qt-5/qlocale.html. This has however been fixed for Qt 4.8, see this entry http://bugreports.qt.io/browse/QTBUG-190 in the Bug Tracker for more information.
In Qt 4.7 and below you can figure out the preferred language using QSettings http://doc.qt.io/qt-5/qsettings.html. See the following example:
QSettings settings("apple.com");
QStringList sl = settings.value("AppleLanguages").toStringList();
qDebug() << "Lang is " << sl.first();
How can I prevent the view from scrolling when the user selects an item in a view?
In order to only allow scrolling when the user drags the scrollbar, you can reimplement scrollTo() http://doc.qt.io/qt-5/qabstractitemview.html#scrollTo to do nothing.
See the following example for a demonstration:
#include <QtWidgets>
class TableWidget : public QTableWidget
{
public:
TableWidget()
{
setColumnCount(15);
setRowCount(20);
QTimer::singleShot(3000, this, SLOT(testScroll()));
}
void scrollTo (const QModelIndex &index, ScrollHint hint = EnsureVisible)
{ }
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
TableWidget table;
table.show();
return app.exec();
}
I am experiencing random crashes when running my application on Windows, what can be wrong?
This sounds like potential memory corruption. which in turn could be caused by conflicting runtime libraries. Make sure you don't have a mismatch of runtime libraries - if you have built Qt in release mode and your application in debug mode this means that it will be using two different runtime libraries. A release C runtime for Qt and a debug C runtime for your application. This means that there are two heaps in use and as a result if objects get passed from one heap to another (i.e. from Qt to the application and vice versa) then memory corruption will occur. You can usually catch this at build time, if you see a link warning about default libraries then this is usually indicative of this problem. The only way to resolve it is to ensure that Qt and your application is built in the same mode.
How to prevent right mouse click selection for a QTreeWidget?
In order to prevent selection of an item when right clicking, you can reimplement QTreeWidget::mousePressEvent() http://doc.qt.io/qt-5/qtreeview.html#mousePressEvent to do nothing if it is the right mouse button which is being clicked. The example below illustrates how this can be done.
#include <QtWidgets>
class TreeWidget : public QTreeWidget
{
public:
TreeWidget()
{
setColumnCount(1);
QList<QTreeWidgetItem *> items;
for (int i = 0; i < 10; ++i)
items.append(new QTreeWidgetItem((QTreeWidget*)0, QStringList(QString(item: %1).arg(i))));
insertTopLevelItems(0, items);
}
void mousePressEvent(QMouseEvent *event)
{
if (event->button()== Qt::RightButton)
return;
else
QTreeWidget::mousePressEvent(event);
}
void contextMenuEvent(QContextMenuEvent *event)
{
QMenu *menu = new QMenu(this);
menu->addAction(first);
menu->addAction(second);
menu->addAction(third);
menu->exec(QCursor::pos());
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
TreeWidget box;
box.show();
return app.exec();
}
My application's plugins won't load on some Windows machines, what can be wrong ?
If you are using Visual Studio 2005 and are using Service Pack 1 then make sure your plugin, your application and Qt is built using the Service Pack as your distributed application will not run otherwise.
Also, when using Visual Studio 2005, make sure you copy the manifest file created when linking the application into the same folder as the application executable.
http://doc.qt.io/qt-5/deployment-windows.html#visual-studio-2005
You also need to include the run time libraries by installing them on the end-user's system.
Also, if you are deploying plugins that depend on a client library, you need to deploy the client library if it does not exist on the target machine. So, if you for example are deploying a mysql plugin, then you need to distribute libmySQL.dll if it does not exist on the target machine.
Also, note that the plugin needs to be located in a subdirectory named according to the type of plugin it is in order for Qt to find it automatically. So if you are using the jpeg plugin for example, the plugin needs to be located in a subdirectory named imageformats within your distribution directory. If you are using a sql driver plugin, it needs to be in a subdirectory called sqldrivers and so on.
See the general documentation on deployment for more details about this:
http://doc.qt.io/qt-5/deployment-windows.html
Is it possible to suppress the scaling of the background of QGraphicsView?
If you use setBackgroundBrush() http://doc.qt.io/qt-5/qgraphicsscene.html#backgroundBrush-prop instead of drawBackground() http://doc.qt.io/qt-5/qgraphicsscene.html#drawBackground on the QGraphicsScene http://doc.qt.io/qt-5/qgraphicsscene.html, you get a static background that does not scale or transform. QBrush http://doc.qt.io/qt-5/qbrush.html can take a QImage http://doc.qt.io/qt-5/qimage.html, QPixmap http://doc.qt.io/qt-5/qpixmap.html, a solid color, different gradients and different patterns.
How can I add version information to my application?
You can use the qmake variable VERSION to add version information to your library or application. See the documentation on the qmake VERSION variable http://doc.qt.io/qt-5/4.7/qmake-variable-reference.html#qt-version
When creating a .dll with a version number embedded then this is done by setting
VERSION = x.y.z.
in the .pro file. This will also cause the major version number to automatically be placed in the target filename. For example, when setting
VERSION = 2.0.5
TARGET = mylib
the output file is called mylib2.dll.
In order to remove the version number from the target name, then you can use the TARGET_EXT http://doc.qt.io/qt-5/qmake-variable-reference.html#target-ext variable. For instance, setting the output filename without the major version number on Windows can be done by setting it like this:
TARGET_EXT = .dll
On Windows, you can alternatively create a resource file http://doc.qt.io/qt-5/qmake-variable-reference.html#rc-file and specify this as part of your application using:
RC_FILE = foo.rc
Note that the version information will not be part of the target filename.
OpenGL and translucent background do not work together due to a limitation
Due to a limitation in window managers, it is not possible to combine OpenGL with a translucent background window (set with WA_TranslucentBackground). The reason for this is because OpenGL is rendered directly onto the screen and the compositor used to enable the translucent background cannot ensure that the OpenGL is rendered correctly.
There is nothing that can be done in Qt to fix this as it needs to be done on the side of the window manager.
To work around this issue you can either just use Qt to render everything and not OpenGL, or you can render the OpenGL into a pixmap and draw that onto your widget instead.
The eclipse integration will not install when using Wascana Desktop Developer, what can be wrong?
When installing the Wascana Desktop Developer the resulting executable for Eclipse is called Wascana.exe. The eclipse integration expects the eclipse.exe filename and cannot find the correct executable. To work around this you can add a dummy file called eclipse.exe to the eclipse directory.
I get errors when building my Qt/Windows project where one of my paths appears to be cut off, what can be wrong?
If the link error is related to part of your path where you have a space in its name then you need to move your application to a directory without spaces as nmake is not able to understand paths with spaces in them. If you have installed Qt into a directory with spaces in it then Qt needs to be reinstalled into a path without spaces.
How can I clone a widget?
Qt has no automated way of copying a widget and its properties. You have two options for achieving this though:
1) If you create the widget and its children as a form (in designer) you can easily recreate it using QUiLoader.
2) You can create a method that asks the control what class it is and then makes a new one. Then the function needs to copy the attributes across and then recurse down the widget tree.
What does the syntax CONFIG(debug,debug|release) mean ? What does the 1st argument specify and similarly what is the 2nd ?
When qmake http://doc.qt.io/qt-5/qmake-manual.html processes a pro file it could process it up to three times depending on what the configuration is set to. Usually it will do it three times. Once for debug, once for release and one final one for debug_and_release. This is so that both configurations can be generated for at the same time. Therefore when it is required to have debug/release specific settings in a pro file then there is a need to check if qmake is processing the pro file with a particular configuration in mind. As debug and release might be in CONFIG at the same time a check for just debug or release is likely to always be true (particularly if you have debug_and_release enabled). So, this construct
CONFIG(debug, debug|release) {
HEADERS += debug.h
SOURCES += debug.c
}
checks for when the debug configuration is being processed comparing where debug and release are mutually exclusive. As CONFIGs are order dependent (ie the last one set will be considered the active config for mutual exclusive sets like debug and release) a second parameter can be used to specify a set of values to consider, for example:
CONFIG = debug
CONFIG += release
CONFIG(release, debug|release): message(Release build!)#will be displayed
CONFIG(debug, debug|release): message(Debug build!) #not displayed
Note that you should use the build_pass variable http://doc.qt.io/qt-5/qmake-variable-reference.html to filter out messages, otherwise you will get messages when it creates the Makefile which will be the configuration specific makefile. When adding the build_pass variable in conjunction with the following scope
build_pass:CONFIG(debug, debug|release) {
message(Debug bulid)
} else:build_pass {
message(Release build)
}
the output will be as follows:
Project MESSAGE: Debug build
Project MESSAGE: Release build
How can I add a non-resource image to a QTextDocument?
You can add a non-resource image to a QTextDocument http://doc.qt.io/qt-5/qtextdocument.html by using the internal class QTextObjectInterface http://doc.qt.io/qt-5/qtextobjectinterface.html for inserting custom objects into a QTextDocument.
The subclass of QTextObjectInterface will result in a handler for the object you would want to draw. Information like the name of the pixmap or geometry information is stored in the QTextFormat http://doc.qt.io/qt-5/qtextformat.html that you specify at QTextCursor::insertText() http://doc.qt.io/qt-5/4.7/qtextcursor.html#insertText time and that are used as arguments to the functions of QTextObjectInterface. See the documentation:
http://doc.qt.io/qt-5/qabstracttextdocumentlayout.html#registerHandler http://doc.qt.io/qt-5/qchar.html#SpecialCharacter-enum http://doc.qt.io/qt-5/qtextformat.html#ObjectTypes-enum
See the following example for an illustration:
#include <QtWidgets>
class MyHandler : public QObject, public QTextObjectInterface
{
Q_OBJECT
Q_INTERFACES(QTextObjectInterface)
public:
MyHandler(QObject* par = nullptr) : QObject(par), px("polygon.png") {}
QSizeF intrinsicSize(QTextDocument *doc, int posInDoc, const QTextFormat &fmt)
{
Q_UNUSED(doc)
Q_UNUSED(posInDoc)
Q_UNUSED(fmt)
return QSizeF(px.size() );
}
void drawObject(QPainter* p, const QRectF &rect, QTextDocument *doc,
int posInDoc, const QTextFormat &fmt)
{
Q_UNUSED(doc)
Q_UNUSED(posInDoc)
Q_UNUSED(fmt)
p->drawPixmap(rect.toRect(), px );
}
private:
QPixmap px;
};
class Widget : public QTextEdit
{
public:
Widget(QWidget* parent = nullptr) : QTextEdit(parent)
{
MyHandler* handler = new MyHandler(this);
document()->documentLayout()->registerHandler(QTextCharFormat::UserObject,
handler);
QTextCharFormat fmt;
fmt.setObjectType(QTextCharFormat::UserObject);
textCursor().insertText("hello");
textCursor().insertText(QString(QChar::ObjectReplacementCharacter), fmt);
textCursor().insertText("world");
}
};
#include "main.moc"
int main(int argc, char **argv)
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
How can I modify the color for individual words for items in a view?
In order to change the color for only some of the words or characters in an item, you need to draw the item yourself. This can be done by subclassing QStyledItemDelegate http://doc.qt.io/qt-5/qstyleditemdelegate.html and reimplementing paint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#paint to draw the text using QPainter::drawText() http://doc.qt.io/qt-5/qpainter.html#drawText-9.
The example below demonstrates how this can be done:
#include <QtWidgets>
class ItemDelegate: public QStyledItemDelegate
{
public:
using QStyledItemDelegate::QStyledItemDelegate;
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const override
{
if (index.row() == 0) {
QRect r;
painter->drawText(option.rect,Qt::TextSingleLine, "Item ", &r);
painter->setPen(Qt::red);
QRect modOptRect = option.rect;
modOptRect.setLeft(option.rect.left() + r.width());
painter->drawText(modOptRect, "1");
} else {
QItemDelegate::paint(painter, option, index);
}
}
};
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QTreeWidget tree;
tree.setItemDelegate(new ItemDelegate);
QTreeWidgetItem *item1= new QTreeWidgetItem();
QTreeWidgetItem *item2= new QTreeWidgetItem();
item2->setText(0, "item 2");
tree.addTopLevelItem(item1);
tree.addTopLevelItem(item2);
tree.show();
return app.exec();
}
What kind of font support does Qt for Embedded Linux offer?
Qt for Embedded Linux has support for TrueType, Postscrip Type1, Windows font files, and BDF fonts, both anti-aliased and conventional. The fonts can be pre-rendered for CPU and storage savings. The fonts are shared between applications. New font engines can easily be added.
Does Qt for Embedded Linux offer support for internationalization?
Yes.Qt for Embedded Linux incorporates all the Qt 4 features that greatly simplify the internationalization process, including: language and font-aware layout, extensive Unicode support, bi-directional language support, and mixed international text all in one document.
Is a GUI software design tool provided with Qt for Embedded Linux?
Yes. Qt for Embedded Linux includes Qt Designer http://doc.qt.io/qt-5/designer-manual.html, the powerful GUI layout and forms builder. Designer files can be generated on Windows, x11 (or Mac) platforms and still be used in Qt for Embedded Linux programs.
What is the difference between Qt for Embedded Linux and Qt/X11?
Qt/X11 is built on top of the x11 window system, but Qt for Embedded Linux provides its own window system and has therefore lower RAM and ROM requirements. With Qt for Embedded Linux, applications will access the display directly for optimal graphics performance. Nonetheless, the API for developing applications is the same for Qt/X11 and Qt for Embedded Linux.
Can Qt for Embedded Linux display on landscape displays in portrait orientation and visa versa?
Yes. Qt for Embedded Linux supports 90, 180 and 270 degree rotation. It is simple to add additional transformations if needed.
Does Qt for Embedded Linux support any screen size?
Yes. Qt for Embedded Linux handles screen sizes from very small to very large screens such as 4000x4000 pixels.
How do I run Qt for Embedded Linux applications without a keyboard?
Run the application with the -nokeyboard option.
In Qt for Embedded Linux, when I create a pen with the style Qt::DashLine and a width of greater than 1, it does not appear to work in QPainter::drawLine(). Is that a limitation of the embedded library?
This is the expected behaviour, caused by the internal structure of the embedded paint engine which is not as complete as that of other platforms.
What kind of IDEs can be used with Qt for Embedded Linux?
Qt for Embedded Linux applications can be developed in full-fledged IDEs such as Qt Creator, Eclipse, KDevelop or other X11 IDEs. Both Eclipse and KDevelop support auto-completion of code and debugging. Most of Qt for Embedded Linux application development can also be done on Windows using Visual studio.
Does the Qt for Embedded Linux graphics subsystem have the capability write the updates only to the frame buffer, or does it always update the complete frame buffer?
Qt for Embedded Linux automatically updates only what has changed, **not** the complete frame.
How do I enable the touch screen in Qt for Embedded Linux?
Qt for Embedded Linux supports touch panels, but you may need to write your own driver.
Qt provides support for Linux Touch Panel and the driver is implemented in the file:
- QTDIR/src/gui/embedded/qmouselinuxtp_qws.cpp*
Additionally Qt for Embedded Linux has support for tslib which indicates that any touch screen supported by tslib can be used in Qt.
Can I execute a Qt for Embedded Linux application on my development PC although my X-server is running?
Yes, by using the Qt Virtual Framebuffer (QVFb).
Why do I receive the following error message when building makeqpf: Some of the required modules (nocrosscompiler) are not available.
To solve this problem do the following:
- Configure and compile Qt for Embedded Linux for the system on which you are compiling (do not cross-compile).
- compile makeqpf.
This does not mean that you cannot cross-compile Qt for Embedded Linux. Copy the Qt for Embedded Linux directory, and let one be compiled for your local system and another one for your target system.
Can I develop software with Qt/X11 or Qt/Windows and easily change to Qt for Embedded Linux?
Yes. Qt for Embedded Linux is source code compatible with the desktop versions of Qt 4.x, so any program working with Qt 4.x will work with Qt for Embedded Linux (as long as it does not contain platform-dependent code, of course).
Is an X server required for Qt for Embedded Linux?
No. Qt for Embedded Linux always runs without an X server. Any Qt for Embedded Linux application can function as the master process, which is not a graphics server like X11 that handles device input and window allocation.
What is a standard way of configuring Qt/e for a desktop system used for developing Qt for Embedded Linux applications?
To configure Qt for Embedded Linux as a shared library on an X86 platform with:
- QVFb support
- debug symbols
- support for 8, 16 and 32 bit depth
- thread support
use the following command:
./configure -qvfb -embedded x86 -debug -depths 8,16,32 -thread -shared.
What are the graphics capabilities of Qt for Embedded Linux?
Qt for Embedded Linux's graphics subsystem provides everything needed to create state-of-the-art user interfaces, including:
- support for semi-transparency (alpha-blending) and anti-aliasing
- optional floating-point coordinate system
- painter paths
- gradients
- support for interchangeable underlying paint engines and off-screen rendering.
- Qt for Embedded Linux integrates SVG 1.1/1.2 Tiny drawings and animations, and additional features for developers using OpenGL.
How do I add true-type fonts when migrating my application from Qt-X11 to Qt for Embedded Linux?
You must copy them to QTDIR/lib/fonts, and specify them in the file QTDIR/lib/fonts/fontdir.
For further information see: http://doc.qt.io/qt-5/qt-embedded-fonts.html
Why do I receive the QVFb Driver Not Found message when running a Qt for Embedded Linux application?
If you receive the message QVFb: Driver Not Found when running a Qt for Embedded Linux application with the options: -qws -display , the problem is that QVFb has not started.
To solve the problem, start QVFb before you start the application.
Why does the compilation of Qt for Embedded Linux fail with the message: dialogs/qprintdialog.cpp:790: cups/cups.h: No such file or directory?
You are missing the cups development package. Install the package and the problem should be solved. If you do not need cups, you can configure Qt with the option -no-cups.
Is there a way to get access to the virtual framebuffer inside a QPixmap, so that we can render to this address, and then blt the result to screen?
Yes. It is Qt for Embedded Linux specific, but you can obtain a pointer to the bits of a QPixmap http://doc.qt.io/qt-5/qpixmap.html. For example:
void SomeClass::someFunc(){
#ifdef Q_WS_QWS
QPixmap pm;
uchar *bits = pm.scanLine(0);
int bytesPerLine = pm.bytesPerLine();
#endif
}
How can I add an accelerated graphics driver?
Qt for Embedded Linux has the capacity to make use of hardware accelerators. To do so for a PCI or an AGP driver, you need to perform the steps outlined in this document http://doc.qt.io/qt-5/qt-embedded-accel.html.
Why is it not allowed to copy QObjects?
The reason it is not possible to copy QObjects http://doc.qt.io/qt-5/qobject.html is that QObject is a polymorphic object, and that polymorphic objects cannot be copied.
QPushButton pushButton;
QObject object = pushButton;
Q_ASSERT(object.metaObject() == &QPushButton::staticMetaObject)
This would assert, and all calls of virtual functions would call QObject's implementation.
Are there any tools for the job of converting Windows MFC dialogs?="Yes, the GUI layout of Windows dialogs can to some degree be automatically translated to the Qt equivalent using KDAB's tool KNUT() http://www.klaralvdalens-datakonsult.se/?page=products&sub
knut
There is no API for this at the moment, so you will have to implement this yourself. In order to do this manually, what needs to be done is to print the header and footer yourself and use QTextDocument::drawContents() http://doc.qt.io/qt-5/qtextdocument.html#drawContents to draw the relevant part of the page that will fit on the paper. In order to do this you need to calculate what area of the page rectangle your header and footer will occupy and the rest is used for the content of the document. By moving the rectangle that gets what needs to be painted each time and translating the painter so that is effectively painting at 0x0 then it will paint the contents for that page as drawContents() http://doc.qt.io/qt-5/qtextdocument.html#drawContents will clip the painting to the specified rectangle. This is put into a while loop that checks that the rectangle to be painted is actually intersecting with the complete contents rectangle.
The following is an example of how it can be implemented:
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication a(argc, argv);
QFile f("test.html");
f.open(QIODevice::ReadOnly);
QString content = f.readAll();
f.close();
QTextDocument td;
td.setHtml(content);
QPrinter p;
QPrintDialog pd(&p, 0);
pd.exec();
td.setPageSize(p.pageRect().size());
QRect innerRect = p.pageRect();
innerRect.setTop(innerRect.top() + 20);
innerRect.setBottom(innerRect.bottom() - 30);
QRect contentRect = QRect(QPoint(0,0), td.size().toSize());
QRect currentRect = QRect(QPoint(0,0), innerRect.size());
QPainter painter(&p);
int count = 0;
painter.save();
painter.translate(0, 30);
while (currentRect.intersects(contentRect)) {
td.drawContents(&painter, currentRect);
count++;
currentRect.translate(0, currentRect.height());
painter.restore();
painter.drawText(10, 10, QString("Header %1").arg(count));
painter.drawText(10, p.pageRect().bottom() - 10, QString("Footer %1").arg(count));
painter.save();
painter.translate(0, -currentRect.height() * count + 30);
if (currentRect.intersects(contentRect))
p.newPage();
}
painter.restore();
painter.end();
return 0;
}
How do I run a Qt for Embedded Linux application without a mouse?
Run your embedded application with the option: -nomouse , this disables the mouse.
Can I use Qt for Embedded Linux on a PXA27x development board with our own version of Linux?
We have several customers successfully using PXA 255 board, and PXA 27x boards. Qt for Embedded Linux should work on any standard Linux which has support for the Linux frame buffer. If there is no Linux frame buffer support (which is very unlikely), it may be necessary to may adapt one of the graphics drivers to your graphics hardware. Qt for Embedded Linux has a specific plug-in API for adding your own graphics driver.
My Qt/Windows application is running out of user handles, as the application contains a huge amount of widgets. What can be done about this ?
In Qt versions below Qt 4.4, Qt will store a user handle for every widget in the application, including child widgets. This means that for every font, widget and so on, a user handle will be created and taking up memory. So having a huge amount of widgets can cause you to run into the user handles limit of windows. To solve this problem you should delete your widgets when they are being closed and recreate them when needed. Alternatively, you can paint your widgets instead of creating widgets, which is much more light weight.
Starting with Qt 4.4 we are using Alien which will give your application handle-less child widgets, causing it to be much more light-weight and resource friendly as we don't allocate user handles for every single widget. We only allocate user handles for top level widgets. See:
http://labs.trolltech.com/blogs/2007/08/09/qt-invaded-by-aliens-the-end-of-all-flicker
Parentheses show up incorrectly for English text in a right-to-left application. What is wrong?
In -reverse mode or when calling
setLayoutDirection(Qt::RightToLeft)
the default text direction is RightToLeft http://doc.qt.io/qt-5/qt.html#LayoutDirection-enum. The display is how the Bidirectional Algorithm http://unicode.org/reports/tr9 defines the output should look.
Using -reverse together with English text will result in some artifacts like this. It's the task of the translator to ensure things look correct in a right to left language. He can do that by adding some special Unicode characters to the translated string (left-to-right marks etc). In Linguist http://doc.qt.io/qt-5/linguist-manual.html, this can be done by right clicking in the translation field and selecting Insert Unicode control character/LRM Left-to-Right mark.
Is there a way to modify the window flags without causing flicker?
It is not possible to make changes to the window flags once the window has been created without causing flicker. Flicker is unavoidable since the window needs to be recreated.
How can I change the width of the scrollbar of QWebView?
The stylesheet API does not yet support styling QWebView http://doc.qt.io/qt-5/qwebview.html, but you can style the webview's scrollbar using the style API.
You can subclass your style (or create a proxy style) and reimplement QStyle::pixelMetric() http://doc.qt.io/qt-5/qstyle.html#pixelMetric to return the width you want when the metric is QStyle::PM_ScrollBarExtent http://doc.qt.io/qt-5/qstyle.html#PixelMetric-enum. QWebView does not actually use a QScrollBar http://doc.qt.io/qt-5/qscrollbar.html, so you need to be a bit sneaky here to get this to work. When QStyle::pixelMetric() is called in this case, the QWidget* http://doc.qt.io/qt-5/qwidget.html passed in is 0 whereas it is the scrollbar in other cases. So you could set the style on the application and check if the widget is 0 in QStyle::pixelMetric(). If it is, you can assume it's the webview asking for it and therefore returning your modified size and if not fall back to the base class.
The example below demonstrates how this can be done:
#include <QtWidgets>
#include <QWebView>
class Style : public QWindowsStyle
{
public:
Style() {}
int pixelMetric (PixelMetric metric, const QStyleOption *option = nullptr, const QWidget *widget = nullptr) const
{
if (metric == QStyle::PM_ScrollBarExtent && widget == nullptr)
return 30;
return QWindowsStyle::pixelMetric(metric, option, widget);
}
};
class WebView : public QWebView
{
public:
WebView()
{
qApp->setStyle(new Style());
load(QUrl("http://doc.qt.io/qt-5/4.5/qwebview.html"));
QTimer::singleShot(5000, this, SLOT(testSlot()));
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
WebView view;
view.show();
return app.exec();
}
I get an 'Error while parsing /XXX/qrc_XXX.cpp, Java Heap Space'. What's the problem ?
You need to increase the maximal amount of memory usable by Eclipse. In order to do so start Eclipse from the command line, with e.g.:
eclipse -vmargs -Xmx1000M
Is there a way of sizing the window so that it is never overlapped by the taskbar (or it doesn't overlap the taskbar)?
What you can do is call QDesktopWidget::availableGeometry() http://doc.qt.io/qt-5/qdesktopwidget.html#availableGeometry to determine what part of the desktop can be used.
The returned rect excludes the taskbar, so as long as you use only that geometry, you can be sure that your window won't be underneath or on top of the taskbar.
How can I draw shadows behind windows ?
This functionality is not supported in the Qt API yet and would therefore have to be done using native system calls. The function you are looking for in the Win32 API is called UpdateLayeredWindow() http://msdn2.microsoft.com/en-us/library/ms633556.aspx.
It requires that you first create a layered window as mentioned in the above documentation. Something similar can be achieved on X11 using an ARGB visual.We have an example of this in our Graphics Dojo http://labs.trolltech.com/page/Graphics/Examples/Examples1.
We plan on implementing support for this in the future:
http://bugreports.qt.io/browse/QTBUG-668
There are other solutions you can use for faking this effect for windows of a static size (useful for splash screens). For instance, you can take a screenshot of the desktop widget using the following code snippet:
QSize SIZE(600, 300);
QRect splashScreenRect(r.width() / 2 - SIZE.width() / 2, r.height() / 2 - SIZE.height() / 2, SIZE.width(), SIZE.height());
QPixmap desktopBg = QPixmap::grabWindow(QApplication::desktop()->winId(), splashScreenRect.x(), splashScreenRect.y(), splashScreenRect.width(), splashScreenRect.height());
Then you would just draw this pixmap as normal and paint using alpha blending on top of it.
How can I display vertical text in the section of a QHeaderView?
The way to do this is to subclass QProxyStyle http://doc.qt.io/qt-5/qproxystyle.html (or another style if don't want to fall back to the default style) and reimplement drawControl() http://doc.qt.io/qt-5/qproxystyle.html#drawControl. In this function you need to handle the CE_HeaderLabel http://doc.qt.io/qt-5/qstyle.html#ControlElement-enum case and draw the text manually after having rotated the painter.
The following is an example of how to do this:
#include <QtWidgets>
class MyStyle : public QProxyStyle
{
public:
MyStyle(QStyle *style) : QProxyStyle(style) {}
void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter,
const QWidget *widget = nulltr) const
{
if (element == QStyle::CE_HeaderLabel) {
const QHeaderView *hv = qobject_cast<const QHeaderView *>(widget);
if (!hv || hv->orientation() != Qt::Vertical)
return QProxyStyle::drawControl(element, option, painter, widget);
const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option);
painter->save();
painter->translate(header->rect.topLeft());
painter->rotate(90);
painter->drawText(0,0,header->text);
painter->restore();
return;
}
return QProxyStyle::drawControl(element, option, painter, widget);
}
};
int main(int argc, char **argv)
{
QApplication a(argc, argv);
a.setStyle(new MyStyle(a.style()));
QTableView tv;
QStandardItemModel *sim = new QStandardItemModel(2,2,&tv);
tv.setModel(sim);
tv.show();
return a.exec();
}
Why does not touching and moving work when running the imagegestures example on Windows 7?
Our gestures examples rely on the native Windows 7 gesture and touch input. If your driver doesn't generate these, then the examples won't work. One easy way to tell if it is the driver causing the problem is to put break points into the *WM_GESTURE* and *WM_TOUCH* message handlers in qapplication_win.cpp. If you hit those breakpoints, your driver supports the Windows 7 touch interface, but Qt doesn't work with it for some reason. In which case this should be reported via the usual channel http://bugreports.qt.io. Otherwise it is most likely an issue caused by your driver not implementing the Windows 7 touch interface.
How can I align the checkboxes in a view?
In order to align the checkboxes in a view, you need to create your own QStyledItemDelegate http://doc.qt.io/qt-5/qstyleditemdelegate.html and reimplement paint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#paint to draw the checkboxes with the alignment that you want.
In order to do this, QStyle::alignedRect() http://doc.qt.io/qt-5/qstyle.html#alignedRect is used to ensure that it is correctly aligned in the center of the rect for the index, then the base implementation is called with the new information so it takes care of rendering the checkbox.
It is also necessary to reimplement QStyledItemDelegate::editorEvent() http://doc.qt.io/qt-5/qabstractitemdelegate.html#editorEvent to handle the toggling of the checkbox correctly since the checkbox has actually been moved to a different position, and therefore the events for the index need to be handled correctly.
The following example demonstrates how this can be done:
#include <QtWidgets>
class ItemDelegate : public QStyledItemDelegate
{
public:
ItemDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {}
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
{
QStyleOptionViewItem viewItemOption(option);
if (index.column() == 0) {
const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
QRect newRect = QStyle::alignedRect(option.direction, Qt::AlignCenter,
QSize(option.decorationSize.width() + 5,option.decorationSize.height()),
QRect(option.rect.x() + textMargin, option.rect.y(),
option.rect.width() - (2 * textMargin), option.rect.height()));
viewItemOption.rect = newRect;
}
QStyledItemDelegate::paint(painter, viewItemOption, index);
}
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option,
const QModelIndex &index) override
{
Q_ASSERT(event);
Q_ASSERT(model);
// make sure that the item is checkable
Qt::ItemFlags flags = model->flags(index);
if (!(flags & Qt::ItemIsUserCheckable) || !(flags & Qt::ItemIsEnabled))
return false;
// make sure that we have a check state
QVariant value = index.data(Qt::CheckStateRole);
if (!value.isValid())
return false;
// make sure that we have the right event type
if (event->type() == QEvent::MouseButtonRelease) {
const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
QRect checkRect = QStyle::alignedRect(option.direction, Qt::AlignCenter,
option.decorationSize,
QRect(option.rect.x() + (2 * textMargin), option.rect.y(),
option.rect.width() - (2 * textMargin),
option.rect.height()));
if (!checkRect.contains(static_cast<QMouseEvent*>(event)->pos()))
return false;
} else if (event->type() == QEvent::KeyPress) {
if (static_cast<QKeyEvent*>(event)->key() != Qt::Key_Space&& static_cast<QKeyEvent*>(event)->key() != Qt::Key_Select)
return false;
} else {
return false;
}
Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked
? Qt::Unchecked : Qt::Checked);
return model->setData(index, state, Qt::CheckStateRole);
}
};
static int ROWS = 3; static int COLS = 1;
class Table : public QTableWidget
{
Q_OBJECT
public:
Table(QWidget *parent = nullptr)
: QTableWidget(ROWS, COLS, parent)
{
setItemDelegate(new ItemDelegate(this));
QTableWidgetItem *item = 0;
for (int i=0; i<rowCount(); ++i) {
for (int j=0; j<columnCount(); ++j) {
setItem(i, j, item = new QTableWidgetItem);
item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsUserCheckable);
item->setCheckState((i+j) % 2 == 0 ? Qt::Checked : Qt::Unchecked);
}
}
}
};
#include "main.moc"
int main(int argc, char **argv)
{
QApplication a(argc, argv);
Table w;
w.show();
return a.exec();
}
How can I dynamically switch between languages in my application using e.g a QComboBox?
In order to achieve this, you can create a function, called e.g retranslateUi() that sets the user visible text for your widgets. It is not possible to switch between the languages without having such a function that gets called every time the language is changed and that returns a translated version of the text by wrapping it with tr() http://doc.qt.io/qt-5/qobject.html#tr.
Now you can connect the activated() http://doc.qt.io/qt-5/qcombobox.html#activated signal of your QComboBox to a slot which will load and install the correct translator. Finally you also need to reimplement the changeEvent() http://doc.qt.io/qt-5/qcombobox.html#changeEvent to check for a LanguageChange http://doc.trolltech.com/qevent.html#Type-enum event and call retranslateUi() when it occurs .
See the following example for a demonstration:
#include <QtWidgets>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow()
{
translator1 = new QTranslator(this);
translator2 = new QTranslator(this);
menu = new QMenu(this);
menuBar()->addMenu(menu);
fileAction = new QAction(this);
menu->addAction(fileAction);
QComboBox *combo = new QComboBox(this);
setCentralWidget(combo);
combo->addItem("fr");
combo->addItem("en");
combo->addItem("sp");
connect(combo, SIGNAL(activated(const QString &)), this, SLOT(changeMyLanguage(const QString &)));
retranslateUi();
}
void retranslateUi()
{
menu->setTitle(tr("File"));
fileAction->setText(tr("First action"));
}
void changeEvent ( QEvent * event )
{
if (event->type() == QEvent::LanguageChange) {
retranslateUi();
}
QMainWindow::changeEvent(event);
}
public slots:
void changeMyLanguage(const QString & string)
{
if(string == QString("fr")) {
translator1->load("t1_fr", ".");
qApp->installTranslator(translator1);
}
if(string == QString("sp")) {
translator2->load("t1_sp", ".");
qApp->installTranslator(translator2);
}
if(string == QString("en")){
qApp->removeTranslator(translator1);
qApp->removeTranslator(translator2);
}
}
private:
QAction *fileAction;
QMenu *menu;
QTranslator *translator1;
QTranslator *translator2;
};
#include "main.moc"
int main(int argc, char **argv)
{
QApplication a(argc, argv);
MainWindow window;
window.resize(50, 50);
window.show();
return a.exec();
}
When building Qt using MinGW I get the following error: Makefile.Debug:24691: *** multiple target patterns. What can be wrong?
You probably have some include and lib paths that are not necessary and are causing problems, if you do:
set INCLUDE=
set LIB=
configure -redo
mingw32-make
that should solve the problem for you.
Also, make sure that sh.exe (usually comes with Cygwin or msys) is not in the PATH either, as MinGW's make tool expects UNIX-makefiles when it is.
How can I span the headers in my QTableView ?
Qt does not provide an API for spanning headers, but you can implement this yourself. You can subclass QHeaderView http://doc.qt.io/qt-5/qheaderview.html and create one section for each of the groups of columns/rows you would like to span and connect signals and slots to have them react to the different columns/rows.
The following example demonstrates how this can be done for spanning thecolumns in the horizontal header.
#include <QtWidgets>
class MyHeaderModel : public QAbstractItemModel
{
public:
MyHeaderModel(QObject *parent = nullptr) : QAbstractItemModel(parent) {}
int columnCount(const QModelIndex &parent = QModelIndex()) const override { return 2; }
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override { return QVariant(); }
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override { return QModelIndex(); }
QModelIndex parent(const QModelIndex &index) const override { return QModelIndex(); }
int rowCount(const QModelIndex &parent = QModelIndex()) const override { return 0; }
};
class MyHeader : public QHeaderView
{
Q_OBJECT
public:
MyHeader(QHeaderView *header, QWidget *parent = nullptr) : QHeaderView(Qt::Horizontal, header), mainHeader(header)
{
setModel(new MyHeaderModel(this));
// This example uses hardcoded groups, you can extend
// this yourself to save the groups
// Group 1 is 0-2 and Group 2 is 3-4
resizeSection(0, getSectionSizes(0, 2));
resizeSection(1, getSectionSizes(3, 4));
connect(this, SIGNAL(sectionResized(int,int,int)), this, SLOT(updateSizes()));
connect(((QTableWidget *)(mainHeader->parentWidget()))->horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(updateOffset()));
setGeometry(0, 0, header->width(), header->height());
updateOffset();
mainHeader->installEventFilter(this);
}
public slots:
void updateSizes()
{
setOffset(mainHeader->offset());
mainHeader->resizeSection(2, mainHeader->sectionSize(2) + (sectionSize(0) - getSectionSizes(0, 2)));
mainHeader->resizeSection(4, mainHeader->sectionSize(4) + (sectionSize(1) - getSectionSizes(3, 4)));
}
void updateOffset()
{
setOffset(mainHeader->offset());
}
protected:
bool eventFilter(QObject *o, QEvent *e)
{
if (o == mainHeader) {
if (e->type() == QEvent::Resize) {
setOffset(mainHeader->offset());
setGeometry(0, 0, mainHeader->width(), mainHeader->height());
}
return false;
}
return QHeaderView::eventFilter(o, e);
}
private:
int getSectionSizes(int first, int second)
{
int size = 0;
for (int a=first;a<=second;++a)
size += mainHeader->sectionSize(a);
return size;
}
QHeaderView *mainHeader;
};
#include "main.moc"
int main(int argc, char **argv)
{
QApplication a(argc, argv);
QWidget w;
QVBoxLayout *vbox = new QVBoxLayout;
QTableWidget *tw = new QTableWidget(5, 5);
MyHeader *h = new MyHeader(tw->horizontalHeader());
vbox->addWidget(tw);
w.setLayout(vbox);
w.show();
return a.exec();
}
How do I make text follow the line/curve and angle of the QPainterPath?
You can set a QTransform http://doc.qt.io/qt-5/qtransform.html on a QPainter http://doc.qt.io/qt-5/qpainter.html causing the painting to follow a transformation. The usual problem is that it's easy to rotate using QTransform::rotate() http://doc.qt.io/qt-5/4.7/qtransform.html#rotate, but since it rotates around origin which is in the top left corner, the coordinates will not match the painting done without a transformation. Using QTransform http://doc.qt.io/qt-5/qtransform.html translation, you can translate the positions back to the original position, and all of this in the name of trigonometry.
#include <QtWidgets>
#include <cmath>
class Widget : public QWidget
{
public:
Widget ()
: QWidget() { }
private:
void paintEvent ( QPaintEvent *)
{
QString hw("hello world");
int drawWidth = width() / 100;
QPainter painter(this);
QPen pen = painter.pen();
pen.setWidth(drawWidth);
pen.setColor(Qt::darkGreen);
painter.setPen(pen);
QPainterPath path(QPointF(0.0, 0.0));
QPointF c1(width()*0.2,height()*0.8);
QPointF c2(width()*0.8,height()*0.2);
path.cubicTo(c1,c2,QPointF(width(),height()));
//draw the bezier curve
painter.drawPath(path);
//Make the painter ready to draw chars
QFont font = painter.font();
font.setPixelSize(drawWidth*2);
painter.setFont(font);
pen.setColor(Qt::red);
painter.setPen(pen);
qreal percentIncrease = (qreal) 1/(hw.size()+1);
qreal percent = 0;
for ( int i = 0; i < hw.size(); i++ ) {
percent += percentIncrease;
QPointF point = path.pointAtPercent(percent);
qreal angle = path.angleAtPercent(percent);
qreal rad =qreal(0.017453292519943295769)*angle; // PI/180
// From the documentation:
/**
QTransform transforms a point in the plane to another point using the following formulas:
x' = m11*x + m21*y + dx
y' = m22*y + m12*x + dy
**/
// So the idea is to find the "new position of the character
// After we apply the world rotation.
// Then translate the painter back to the original position.
qreal sina = std::sin(rad);
qreal cosa = std::cos(rad);
// Finding the delta for the penwidth
// Don't divide by 2 because some space would be nice
qreal deltaPenX = cosa * pen.width();
qreal deltaPenY = sina * pen.width();
// Finding new posision after rotation
qreal newX = (cosa * point.x()) - (sina * point.y());
qreal newY = (cosa * point.y()) + (sina * point.x());
// Getting the delta distance
qreal deltaX = newX - point.x();
qreal deltaY = newY - point.y();
// Applying the rotation with the translation.
QTransform tran(cosa,sina,-sina,cosa,-deltaX + deltaPenX,-deltaY - deltaPenY);
painter.setWorldTransform(tran);
painter.drawText(point,QString(hw[i]));
}
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
Widget widget;
widget.show();
return app.exec();
}
When I run my Qt for Embedded Linux application I get the error message Can't drive depth 32.
Your problem is most likely that you did not configure with support for the bit depth which the screen supports. To specify which bit depths you want Qt for Embedded Linux to support, use the configure option depths. For example:
./configure -qvfb -embedded x86 -debug -depths 8,16,32 -thread
I want to run my Qt for Embedded Linux application on the QVFb, but I get the message Can't open framebuffer device /dev/fb0 : driver cannot connect.
You must specify a -display option for the program as follows:
./fooprog -qws -display LinuxFb
Where do I put the plug-in library file for a touch screen driver plug-in?
The library should be put in yourQtDirectory/plugins/mousedrivers where it will be automatically found.
setClickable() and setSortIndicatorShown() affect the entire QHeaderView, is there a way to have it affect only certain sections?
There is no direct API for this at the moment, so for the time being, you need to reimplement the mousePressEvent() http://doc.qt.io/qt-5/qheaderview.html#mousePressEvent and mouseReleaseEvent() http://doc.qt.io/qt-5/qheaderview.html#mouseReleaseEvent for the headerview and check which section is being pressed on, then if it is one you want to allow to be movable, or clickable, you turn it on before calling the base implementation. In the mouseReleaseEvent() you would turn off the movable/clickable properties.
When it comes to setSortIndicatorShown() http://doc.qt.io/qt-5/qheaderview.html#showSortIndicator-prop, then it is expected that the indicator will be shown until the user clicks on another section. So in mousePressEvent() we hide the indicator if the section clicked is not the one that should show the indicator. Alternatively the sort indicator can simply stay on the section clicked previously.
The example below demonstrates how this can be done.
#include <QtWidgets>
class HeaderView : public QHeaderView
{
Q_OBJECT
public:
HeaderView(QWidget *parent = nullptr) : QHeaderView(Qt::Horizontal, parent)
{
connect(this, &QHeaderView::sectionClicked, this, &HeaderView::clickedSection);
}
void mousePressEvent(QMouseEvent *event) override
{
if(visualIndexAt(event->pos().x()) == 1) {
setClickable(true);
setSortIndicator(1, sortIndicatorOrder());
setSortIndicatorShown(true);
} else {
setSortIndicatorShown(false);
resizeSection(1, sectionSize(1) - 1);
resizeSection(1, sectionSize(1) + 1);
}
QHeaderView::mousePressEvent(event);
}
void mouseReleaseEvent(QMouseEvent *event) override
{
QHeaderView::mouseReleaseEvent(event);
setClickable(false);
}
public slots:
void clickedSection(int s)
{
qDebug() << "Section " << s << " clicked";
}
};
class TreeWidget : public QTreeWidget
{
public:
TreeWidget()
{
setColumnCount(3);
QStringList list;
list << "a" << "b" << "c";
QStringList list2;
list2 << "d" << "e" << "f";
QTreeWidgetItem *item1 = new QTreeWidgetItem(this, list);
QTreeWidgetItem *item2 = new QTreeWidgetItem(this, list2);
addTopLevelItem(item1);
addTopLevelItem(item2);
setHeader(new HeaderView(this));
}
};
#include "main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
TreeWidget tree;
tree.show();
return app.exec();
}
How can I debug the Qt source files when running my application inside Visual Studio?
You can debug the Qt source files if you have made the relevant Qt modules, e.g QtCore and QtGui part of your solution.
If you are using the Visual Studio Add-in, then checking the Debugger Extension option while installing should have provided you with an autoexp.dat file in %VSINSTALLDIR%\Common7\Packages\Debugger that provides debugging support for the Qt classes. Make sure that this autoexp.dat file exists and that it contains an [AutoExpand] section that contains references to various Qt classes. If it does not exist, then uninstall and reinstall the Add-in.
How can QTextCursor be used to select a row in a QTextTable?
All that needs to be done to select the whole row is get the cells for the first and last column in the row, and then getting the relevant positions from those cells. With those positions you can select the text using setPosition() http://doc.qt.io/qt-5/qtextcursor.html#setPosition and keeping the anchor. An example piece of code is as follows:
QTextTable *tt = textEdit->textCursor().currentTable();
if (!tt)
return;
QTextCursor cursor = textEdit->textCursor();
QTextTableCell cell = tt->cellAt(cursor);
QTextTableCell rowStart = tt->cellAt(cell.row(), 0);
QTextTableCell rowEnd = tt->cellAt(cell.row(), tt->columns() - 1);
cursor.setPosition(rowStart.firstCursorPosition().position());
cursor.setPosition(rowEnd.lastCursorPosition().position(), QTextCursor::KeepAnchor);
textEdit->setTextCursor(cursor);
How do I apply patch files to Qt source files?
To apply a patch automatically you need a program called `patch'. `patch' takes a patch file containing a difference listing produced by diff and applies those differences to one or more original files, producing patched versions.
If you are running windows, you can download it from here:
http://gnuwin32.sourceforge.net/packages/patch.htm
On the Mac and on X11 a patch program is provided with the system.
http://gnuwin32.sourceforge.net/packages/patch.htm
When dragging and dropping between 2 views, how can I perform a move without pressing Shift?
When dragging and dropping between 2 views then a copy will be done by default when not pressing Shift. If you need to make it a Move action instead, then you can call
setDropAction(Qt::MoveAction)
in the dragEnterEvent() http://doc.qt.io/qt-5/qabstractitemview.html#dragEnterEvent, dragMoveEvent() http://doc.qt.io/qt-5/qlistview.html#dragMoveEvent and the dropEvent() http://doc.qt.io/qt-5/qlistwidget.html#dropEvent. Doing so will override the proposed action http://doc.trolltech.com/dnd.html#overriding-proposed-actions.
See the following example for a demonstration:
#include <QtWidgets>
class ListWidget : public QListWidget {
Q_OBJECT
public:
ListWidget() : QListWidget(0)
{
setAcceptDrops(true);
setDragEnabled(true);
QListWidgetItem *item1 = new QListWidgetItem(tr("Oak"), this);
QListWidgetItem *item2 = new QListWidgetItem(tr("Fir"), this);
QListWidgetItem *item3 = new QListWidgetItem(tr("Pine"), this);
}
void dragEnterEvent(QDragEnterEvent *e)
{
QListWidget::dragEnterEvent(e);
if (e->keyboardModifiers() == Qt::NoModifier) { e->setDropAction(Qt::MoveAction);
e->accept();
} else if (e->proposedAction() == Qt::MoveAction)
e->acceptProposedAction();
}
void dragMoveEvent(QDragMoveEvent *e)
{
QListWidget::dragMoveEvent(e);
if (e->keyboardModifiers() == Qt::NoModifier) { e->setDropAction(Qt::MoveAction);
e->accept();
} else if (e->proposedAction() == Qt::MoveAction)
e->acceptProposedAction();
}
void dropEvent(QDropEvent *e)
{
if (e->keyboardModifiers() == Qt::NoModifier) {
QListWidget::dropEvent(e);
e->setDropAction(Qt::MoveAction);
e->accept();
} else if (e->proposedAction() == Qt::MoveAction) {
QListWidget::dropEvent(e);
e->acceptProposedAction();
} else
QListWidget::dropEvent(e);
}
};
#include "main.moc"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QWidget wid;
ListWidget *box = new ListWidget;
ListWidget *box2 = new ListWidget
QVBoxLayout layout(&wid);
layout.addWidget(box);
layout.addWidget(box2);
wid.show();
return app.exec();
}
How can I get rid of the sizegrip of a window on Mac OS X?
Qt/Mac uses the sizegrip given from Mac OS X. When calling
statusBar()->setSizeGripEnabled(true)
the status bar creates a QSizeGrip http://doc.qt.io/qt-5/qsizegrip.html, hides the native Mac OS X size grip, and places the QSizeGrip in the same location as the native size grip. If you don't want any sizegrip to appear, then you need to give your window a fixed size. If you don't want to give your window a fixed size, then you can use the QSizeGrip provided by Qt and call setFixedSize(0,0) on that one, e.g:
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
#if 1
QMainWindow box;
box.statusBar()->setSizeGripEnabled(true);
QSizeGrip *grip = box.statusBar()->findChild<QSizeGrip*>();
#else
QDialog box;
QStatusBar *grip = new QStatusBar(&box);
#endif
box.show();
grip->setFixedSize(0,0);
return app.exec();
}
How do I add a custom Info.plist to my Mac application with qmake?
You can set your own Info.plist by setting the QMAKE_INFO_PLIST variable to your Info.plist file. qmake will add a rule in the Makefile it generates to copy this over. If you don't specify this, qmake provides a generic Info.plist file.
QMAKE_INFO_PLIST = MyInfo.plist # qmake will copy this file to MyApp.app/Contents/Info.plist
How often will new Qt SDK packages be released?
A new SDK package will be released each time a new Qt version is released, or when a new minor version (1.x) of Qt Creator is released.
Why is it only possible to draw in the GUI thread and how can this be worked around?
X11 does rendering in a single thread so even if you use different threads to draw, the drawing will be serialized in the X server thread, so there is no benefit from drawing in different threads.
On Windows the same is true. Since Qt normally relies on the underlying Windowing System, we don't provide this option. However, we do provide the option to render into a QImage from a Non-GUI thread, as this is a pure software solution only partially relying on the underlying system. It is also possible to do multi-threaded text layout and printing, see:
http://blog.qt.io/2007/09/27/multi-threaded-text-layout-and-printing/
Please note that unless your software is running on machines that have multiple CPU's, splitting rendering into threads will not give you any significant speed improvements (we have experiences that hyper threading usually slows performance down in a single application)
According to our measurements, you can on a desktop computer draw approximately 500 000 triangles (10*10 pixels) per second.
How can I make the text of a disabled widget look enabled?
In order to make the text of a disabled widget look enabled, you can change the color of the disabled colorgroup in the palette to have the same color as the active color group. See the documentation on QPalette::setColor() http://doc.qt.io/qt-5/qpalette.html#setColor
The following example demonstrates how this can be done for a QLineEdit http://doc.qt.io/qt-5/qlineedit.html:
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QLineEdit edit;
edit.setText("Lineedit");
edit.setDisabled(true);
QPalette pal = edit.palette();
pal.setColor(QPalette::Disabled, QPalette::Text, pal.color(QPalette::Active, QPalette::Text));
pal.setColor(QPalette::Disabled, QPalette::Base, pal.color(QPalette::Active, QPalette::Base));
edit.setPalette(pal);
edit.show();
return app.exec();
}
Why do you provide container classes as an alternative to STL in Qt?
We want our container classes to behave in the same way on all platforms. The different compilers might have different implementations of STL, so the behavior can vary. In addition when we created the container classes, not all platforms had decent implementations of STL. Finally, we provide QString http://doc.qt.io/qt-5/qstring.html which is a string class which provides a string of unicode characters. Since QString is available on all platforms, we can be sure that it will work for passing unicode characters from one place to another.
How do I create a default size for the rows in a table view?
In order to change the default size for the rows in a table view, you need to reimplement sizeHintForRow() http://doc.qt.io/qt-5/qtableview.html#sizeHintForRow and make sure resizeRowToContents() http://doc.qt.io/qt-5/qtableview.html#resizeRowToContents is called.
The example below demonstrates how this can be achieved
#include <QtWidgets>
class Model : public QAbstractTableModel
{
public:
Model(QObject *parent)
{
QStringList firstRow;
QStringList secondRow;
for (int i = 0; i < 5; i++ ) {
firstRow.insert(i,"Row 1 " + QString::number(i+1));
secondRow.insert(i,"Row 2 " + QString::number(i+1));
}
stringList << firstRow << secondRow;
}
// Returns the number of rows
int rowCount ( const QModelIndex & parent = QModelIndex() ) const
{
return stringList.count();
}
// Returns the number of columns
int columnCount ( const QModelIndex & parent = QModelIndex() ) const
{
return stringList[0].count();
}
// Returns an appropriate value for the requested data.
// If the view requests an invalid index or if the role is not
// Qt::DisplayRole, an invalid variant is returned.
// Any valid index that corresponds to a string for the index's column and row in
// the stringlist is returned
QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const
{
if (!index.isValid())
return QVariant();
if (role != Qt::DisplayRole)
return QVariant();
QStringList list = (QStringList)stringList.at(index.row());
return list.at(index.column());
}
private:
QList<QStringList>stringList;
};
class TableView : public QTableView
{
public:
TableView(QWidget *parent) {}
//Returns the needed size for the rows
int sizeHintForRow ( int row ) const
{
return 200;
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QWidget widget;
QHBoxLayout *layout = new QHBoxLayout(&widget);
TableView *tableView = new TableView(&widget);
Model *model = new Model(tableView);
tableView->setModel(model);
for (int i = 0; i < model->rowCount(); i++) {
tableView->resizeRowToContents(i);
}
layout->addWidget(tableView);
widget.show();
return app.exec();
}
How can I embed e.g a QMainWindow inside a QDialog ?
In order to embed a toplevel window inside another window you need to create the embedded window without a parent and then call setParent() http://doc.qt.io/qt-5/qwidget.html#setParent on it after the embedded window has been constructed.
See the following example for an illustration:
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QDialog box;
QMainWindow *window = new QMainWindow(0);
QTextEdit *edit = new QTextEdit(window);
window->setCentralWidget(edit);
QVBoxLayout *layout = new QVBoxLayout(&box);
layout->addWidget(window);
QMenu *menu = new QMenu("file", window);
menu->addAction("one");
menu->addAction("one");
menu->addAction("one");
window->menuBar()->addMenu(menu);
window->setParent(&box);
return box.exec();
}
How do I set the width or height of the header sections in a view?
You can set the width or height of the header sections in a view by calling QHeaderView::resizeSection() http://doc.qt.io/qt-5/qheaderview.html#resizeSection. The QHeaderView class provides a header row or header column for item views, and you can use the header() http://doc.qt.io/qt-5/qtreeview.html#header, horizontalHeader() http://doc.qt.io/qt-5/qtableview.html#horizontalHeader or verticalHeader() http://doc.qt.io/qt-5/qtableview.html#verticalHeader (depending on what your view is) functions to access them.
#include <QApplication>
#include <QTableWidget>
#include <QHeaderView>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QTableWidget table(2,2);
QTableWidgetItem *itemOne = new QTableWidgetItem("one");
table.setItem(0,0,itemOne);
table.horizontalHeader()->resizeSection(0, 200);
table.verticalHeader()->resizeSection(1, 200);
table.show();
return app.exec();
}
How can I sort the items in a QTableWidget on multiple columns?
This will depend a little on the size of your dataset. Since we use a stable sort you can relatively easily achieve this by keeping a list of sort columns and sort them from last to first.
See the example below for a demonstration.
If you have a lot of records you might want to implement your own model that will more efficiently sort based on multiple columns.
#include <QtWidgets>
#define SETPERSON(index, first, second, salary) setItem(index, 0, new QTableWidgetItem(first));
setItem(index, 1, new QTableWidgetItem(second));
setItem(index, 2, new QTableWidgetItem);
item(index, 2)->setData(Qt::DisplayRole, salary);
class Table : public QTableWidget
{
Q_OBJECT
public:
Table(QWidget *parent = nullptr)
: QTableWidget(6, 3, parent)
{
SETPERSON(0, "Jerry", "Springer", 1000000);
SETPERSON(1, "Foo", "Springer", 12341);
SETPERSON(2, "John", "Wayne", 12341);
SETPERSON(3, "Bob", "Carver", 80000);
SETPERSON(4, "Bob", "Carver", 81000);
SETPERSON(5, "Bob", "Ulong", 60000);
updateSortOrder();
connect(horizontalHeader(), SIGNAL(sectionClicked(int)),
this, SLOT(onHeaderClicked(int)));
disconnect(horizontalHeader(), SIGNAL(sectionPressed(int)), this, SLOT(selectColumn(int)));
}
void updateSortOrder()
{
QStringList list;
list << "First name" << "Last name" << "Salary";
for (int i=0; i<sortOrder.size(); ++i)
list[sortOrder.at(i).column].append("(" + QString::number(i + 1) + ")");
setHorizontalHeaderLabels(list);
for (int i=sortOrder.size() - 1; i>=0; --i) {
sortItems(sortOrder.at(i).column, sortOrder.at(i).ascending ? Qt::AscendingOrder : Qt::DescendingOrder);
}
}
public slots:
void onHeaderClicked(int section)
{
bool ascending = true;
if (!(QApplication::keyboardModifiers() & Qt::ControlModifier) || sortOrder.isEmpty()) {
if (!sortOrder.isEmpty() && sortOrder.first().column == section) {
ascending = !sortOrder.first().ascending;
}
sortOrder.clear();
} else {
const int index = findSection(section);
if (index != -1) {
if (index == sortOrder.size() - 1) {
ascending = !sortOrder.last().ascending;
}
sortOrder.removeAt(index);
}
}
sortOrder.append(SortData(section, ascending));
updateSortOrder();
}
private:
int findSection(int section) const
{
for (int i=0; i<sortOrder.size(); ++i) {
if (sortOrder.at(i).column == section)
return i;
}
return -1;
}
struct SortData {
SortData(int sec = -1, bool asc = true) : column(sec), ascending(asc) {}
int column;
bool ascending;
};
QList<SortData> sortOrder;
};
#include "main.moc"
int main(int argc, char **argv)
{
QApplication a(argc, argv);
Table w;
w.show();
return a.exec();
}
You need to do a little extra to get this working. This is a requirement of Mac OS X and not of Qt. You can find information on this here http://doc.qt.io/qt-5/mac-differences.html#translating-the-application-menu-and-native-dialogs.
Since the application menu is not really controlled by Qt, you have to play by the rules of the operating system. If you want the menu to show up in e.g German then you can simply create a folder called de.lproj and put that in the yourApp.app/Contents/Resources folder in your bundle. Inside the de.lproj folder you put the localisation.plist which should have contents similar to that shown in the documentation. So if you want the menu to show up in German, simply change the value of the
<key>LprojLocale</key> to de.
You can take a look at the contents of many of your applications installed in /Applications. They should be similar to what's described here.
When reimplementing the contextMenuEvent() http://doc.qt.io/qt-5/qabstractscrollarea.html#contextMenuEvent in a view to pop up a menu where the cursor is located, then you can pass in the cursor's global position as an argument to exec() http://doc.qt.io/qt-5/qmenu.html#exec. For determining which cell was clicked then simply use the event's pos() http://doc.qt.io/qt-5/qcontextmenuevent.html#pos value as an argument to indexAt() http://doc.qt.io/qt-5/qtableview.html#indexAt and get the QModelIndex that way.
The example below demonstrates how this can be done for a QTableView:
#include <QtWidgets>
class Model : public QAbstractTableModel
{
public:
Model(QObject *parent) : QAbstractTableModel(parent)
{
QStringList firstRow;
QStringList secondRow;
for (int i = 0; i < 15; i++ ) {
firstRow.insert(i,"Row 1 " + QString::number(i+1));
secondRow.insert(i,"Row 2 " + QString::number(i+1));
}
stringList << firstRow << secondRow;
}
int rowCount ( const QModelIndex & parent = QModelIndex() ) const
{
return stringList.count();
}
int columnCount ( const QModelIndex & parent = QModelIndex() ) const
{
return stringList[0].count();
}
QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const
{
if (!index.isValid())
return QVariant();
if (role != Qt::DisplayRole)
return QVariant();
QStringList list = (QStringList)stringList.at(index.row());
return list.at(index.column());
}
private:
QList<QStringList>stringList;
};
class TableView : public QTableView
{
public:
TableView(QWidget *parent) : QTableView(parent)
{}
void contextMenuEvent ( QContextMenuEvent * e )
{
QMenu *menu = new QMenu(this);
QModelIndex index = indexAt(e->pos());
if (index.isValid())
menu->addAction(QString("Row %1 - Col %2 was clicked on").arg(index.row()).arg(index.column()));
else
menu->addAction("No item was clicked on");
menu->exec(QCursor::pos());
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QWidget widget;
QHBoxLayout *layout = new QHBoxLayout(&widget);
TableView *tableView = new TableView(&widget);
Model *model = new Model(tableView);
tableView->setModel(model);
layout->addWidget(tableView);
widget.show();
return app.exec();
}
Intellisense does not work for my Qt application. What's wrong?
When writing code that uses the class generated from a ui file, the intellisense does not appear to list the functions for it.
There are several reason why this happens:
1. You are currently in the function body in a slot. The VS intellisense parser gets confused by the slot keyword in the header file and stops therefore working. As an easy workarround for this just place a ';' behind the slots declaration, e.g.:
public slots:;
void mySlot();
2. The class/struct is not directly included. Sometimes the completion on e.g. a push button object does not work since you included <QtGui>. For compilation it's of course perfect, but intellisense may not work correctly with this information. Try to include <QtGui/QPushButton> instead/in addition.
3. The C++ source code has not been generated yet. Intellisense works only on C++ code, but when designing a form there is no C++ code directly involved. The C++ code is generated by uic which must be run after the ui file is saved. So, whenever you added or removed an item from the form you have to run uic on it. This can easily be done by opening the context menu for the ui file in the solution explorer and clicking on compile. Another, more comfortable, way of doing this is enabling the AutoRunUic property in Tools|Options|Qt|General options page. This basically saves the form and runs uic whenever you leave the form editor.
4. Make sure you open Visual Studio using the command prompt provided with Qt in the Start menu if you are using the binary package or from a command prompt that has the environment set correctly if you are using the source package.
If it's only happening with a specific project, then try deleting (or renaming to be safe) the .ncb and .suo file for that project. These will be regenerated when the project is opened and built, respectively, and could help if the problem is due to some sort of corruption in those files.
Is it possible to reimplement non-virtual slots?
When a class is subclassed and a slot is reimplemented, regardless of whether it is virtual or not, the meta object for the subclass is the one that is queried for the slot and therefore it actually finds the reimplemented slot.
There can be situations where your reimplemented slot does not get called however. If the connections for the slot are created in the base class's constructor for example, then it is not able to access the subclass's metaobject since the virtual table isn't ready at this point and since metaObject() http://doc.qt.io/qt-5/qobject.html#metaObject is a virtual function it will end up with the base class's implementation of it. Since you cannot get the reimplemented virtual function of a class in its base class constructor you need to trigger the connections to be set up again at a point where the metaobject of the subclass can be gotten hold of.
In the example below, we have reimplemented columnResized() http://doc.qt.io/qt-5/qtableview.html#columnResized for a QTableWidget subclass. Since the connection for columnResized() is set up indirectly from the QTableWidget's constructor (in the setHorizontalHeader() http://doc.qt.io/qt-5/4.7/qtableview.html#setHorizontalHeader function), then we need to trigger setHorizontalHeader() to get called again after the tablewidget subclass is constructed. We do this by creating a new header and setting it up in a slot connected to a single shot timer.
#include <QtWidgets>
class TableWidget : public QTableWidget
{
Q_OBJECT
public:
TableWidget() : QTableWidget(10, 10)
{
QTimer::singleShot(0, this, SLOT(fixHeader()));
}
public slots:
void fixHeader()
{
QHeaderView *hv = new QHeaderView(Qt::Horizontal, this);
hv->setHighlightSections(true);
hv->setClickable(true);
setHorizontalHeader(hv);
hv->show();
}
protected slots:
void columnResized(int a, int b, int col)
{
qDebug() << "This is called";
}
};
#include "main.moc"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
TableWidget box;
box.show();
return app.exec();
}
When running on Linux then Eclipse crashes frequently. The 'problematic frame' seems to be 'gtk_tooltips_set_tip+0x1dc'. What is the problem ?
This is a problem of Eclipse on certain platforms, and is not related to the Qt Eclipse Integration. See for example here:
https://bugs.launchpad.net/ubuntu/+source/eclipse/+bug/128232
Does Qt for Embedded Linux support mouse shortcuts?
Yes. The following shortcuts are supported:
- double-click the title bar
- right-click to expose menus
- shift-click to select consecutive list items or text
- ctrl-click to select non-consecutive list items
- click-n-drag to select text
- double-click to select a word of text
How can I make a QComboBox have multiple selection?
With the example given below, you can currently do multiple selection by dragging the mouse over the items you want to select. There is only one thing left that needs to be done, and that's to decide how you want to make the combobox's popup disappear. This is not illustrated in the example, but all you need to do is install an event filter on the view for the combobox and when you get a mouse button release, you can either eat the event or let it carry on. Eating it would prevent it from closing the popup and therefore allow you to close it when you want. As long as you call hidePopup() http://doc.qt.io/qt-5/qcombobox.html#hidePopup when you want it to be closed, then it will ensure that everything is updated as appropriate.
#include <QtWidgets>
class MyComboBox : public QComboBox
{
Q_OBJECT
public:
MyComboBox(QWidget *parent = nullptr) : QComboBox(parent)
{
addItem("A");
addItem("B");
addItem("C");
setEditable(true);
lineEdit()->setReadOnly(true);
view()->setSelectionMode(QAbstractItemView::MultiSelection);
}
void showPopup()
{
QComboBox::showPopup();
QStringList strs = str.split(" ");
QAbstractItemModel *model = view()->model();
for (int i=0;i<strs.size();++i) {
QModelIndexList idxes = model->match(model->index(0, 0), Qt::DisplayRole, strs.at(i), 1,
Qt::MatchExactly);
foreach(QModelIndex idx, idxes)
view()->selectionModel()->select(idx, QItemSelectionModel::Select);
}
}
void hidePopup()
{
QItemSelectionModel *ism = view()->selectionModel();
QModelIndexList idxes = ism->selectedIndexes();
str = "";
foreach(QModelIndex idx, idxes)
str += idx.data().toString() + " ";
QComboBox::hidePopup();
QTimer::singleShot(0, this, SLOT(updateText()));
}
public slots:
void updateText()
{
lineEdit()->setText(str);
}
private:
QString str;
};
#include "main.moc"
int main(int argc, char **argv)
{
QApplication a(argc, argv);
MyComboBox b;
b.show();
return a.exec();
}
How can I draw vertical text?
Drawing vertical text can be done in several ways. The easiest way might be to create a QTextDocument http://doc.qt.io/qt-5/qtextdocument.html in the paintEvent() http://doc.qt.io/qt-5/qwidget.html#paintEvent and use setHtml() http://doc.qt.io/qt-5/qtextdocument.html#setHtml to set the text and specify the
<br/>
tag to get line breaks. Another way could be to iterate over the QChars http://doc.qt.io/qt-5/qchar.html in the QString http://doc.qt.io/qt-5/qstring.html and position them vertically in the paintEvent() yourself. Then you would need to calculate the height between each element.
If what you want is rotated text, then you can simply rotate the painter 90 degrees.
Finally, if you are not going to draw the text yourself, then a QLabel http://doc.qt.io/qt-5/qlabel.html can easily be used to display vertical text, simply by specifying \n after each character.
The example below illustrates some of the possibilities:
#include <QtWidgets>
class Widget : public QWidget
{
public:
Widget(QWidget *parent = nullptr)
: QWidget(parent)
{}
void paintEvent(QPaintEvent *)
{
QPainter p(this);
#if 1
QTextDocument document;
document.setHtml("<br>T<br>e<br>s<br>t<br>");
document.drawContents(&p);
#else
drawRotatedText(&p, 90, width() / 2, height() / 2, "The vertical text");
#endif
}
void drawRotatedText(QPainter *painter, float degrees, int x, int y, const QString &text)
{
painter->save();
painter->translate(x, y);
painter->rotate(degrees);
painter->drawText(0, 0, text);
painter->restore();
}
};
int main(int argc, char **argv)
{
QApplication a(argc, argv);
Widget w;
w.resize(200,200);
QString string = "t\ne\ns\nt";
QLabel label;
label.setText(string);
label.show();
w.show();
return a.exec();
}
I would like to detect if the expansion sign has been clicked in my QTreeView. How can this be achieved?
If you want to be notified when the user clicks the expansion button for the items in your tree, then you can reimplement the mousePressEvent() http://doc.qt.io/qt-5/qtreeview.html#mousePressEvent and calculate the position of the expansion sign. If the mouse is over the calculated position, then you can for example emit a signal to notify it and do your own handling. Otherwise, simply call the base implementation.
The following example demonstrates how this can be done:
#include <QtWidgets>
class TreeWidget : public QTreeWidget
{
public:
TreeWidget()
{
setColumnCount(1);
item1 = new QTreeWidgetItem(this);
item1->setText(0, "item 1");
item1->setExpanded(true);
item2 = new QTreeWidgetItem(item1);
item2->setText(0, "item 2");
item2->setExpanded(true);
item3 = new QTreeWidgetItem(item2);
item3->setText(0, "item 3");
item4 = new QTreeWidgetItem(item1);
item4->setText(0, "item 4");
}
void mousePressEvent(QMouseEvent *event)
{
QModelIndex indexClicked = indexAt(event->pos());
if(indexClicked.isValid())
{
QRect vrect = visualRect(indexClicked);
int itemIndentation = vrect.x() - visualRect(rootIndex()).x();
QRect rect = QRect(header()->sectionViewportPosition(0) + itemIndentation -
indentation(), vrect.y(), indentation(), vrect.height());
if(rect.contains(event->pos()) && model()->hasChildren(indexClicked)) {
qDebug() << "plus clicked";
QTreeWidget::mousePressEvent(event);
return;
} else {
QTreeWidget::mousePressEvent(event);
}
}
}
private:
QTreeWidgetItem *item1;
QTreeWidgetItem *item2;
QTreeWidgetItem *item3;
QTreeWidgetItem *item4;
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
TreeWidget box;
box.show();
return app.exec();
}
How can I catch Alt+F4 in my Qt application ?
Alt+F4 is a key combination controlled by Windows and Qt has no control over such system keys. What you can try to get around this is to start a QTimer to calculate the time from when Alt is pressed until the widget receives a closeEvent() http://doc.qt.io/qt-5/qwidget.html#closeEvent. If the closeEvent() http://doc.qt.io/qt-5/qwidget.html#closeEvent is received before e.g 300 msecs have passed, you can assume that Alt+F4 was pressed. See the following example for an illustration:
#include <QtWidgets>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow() : QMainWindow()
{
altPressed = false;
installEventFilter(this);
}
void closeEvent(QCloseEvent *event)
{
if (altPressed) {
qDebug() << Alt + f4 was pressed, causing shutdown;
} else {
qDebug() << Alt + f4 was not pressed. Shutting down for another reason;
}
QMainWindow::closeEvent(event);
}
bool eventFilter(QObject *o, QEvent *e)
{
if (e->type() == QEvent::ShortcutOverride) {
QKeyEvent *event = (QKeyEvent *)e;
if(event->modifiers() == Qt::AltModifier) {
altPressed = true;
QTimer::singleShot(300, this, SLOT(testSlot()));
return false;
}
}
return QMainWindow::event(e);
}
public slots:
void testSlot()
{
qDebug() << Only Alt was pressed;
altPressed = false;
}
private:
bool altPressed;
};
#include main.moc"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
MainWindow main;
main.show();
return app.exec();
}
The reason why About shows up instead of A propos in this situation is that the About text is set by Qt. Preferences, Quit, etc are given the standard Carbon commands, so Carbon can detect which language to display them in provided that you have the correct .lproj in your application bundle. Since there is no general way to translate the About text, you can provide the text you want by subclassing QTranslator http://doc.qt.io/qt-5/qtranslator.html and reimplementing translate() http://doc.qt.io/qt-5/qtranslator.html#translate to return the text you want.
See the following example for an illustration:
#include <QtWidgets>
class Translator : public QTranslator
{
Q_OBJECT
public:
Translator(QWidget* parent=0) : QTranslator(parent) {}
QString translate(const char *context, const char *sourceText,
const char *comment = nullptr) const
{
if (QString(context).compare("QMenuBar") == 0 &&
QString(sourceText).compare("About %1") == 0) {
return QString("Apropos d' %1");
}
return sourceText;
}
};
#include "main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
Translator translator;
app.installTranslator(&translator);
QMainWindow window;
QMenu *menu = window.menuBar()->addMenu("Test");
QAction *firstAction = menu->addAction(QObject::tr("Random text"));
firstAction->setMenuRole(QAction::AboutRole);
QAction *secondAction = menu->addAction(QObject::tr("Preferences"));
secondAction->setMenuRole(QAction::PreferencesRole);
window.show();
return app.exec();
}
How can I have a partially transparent pixmap on my toplevel window?
For top level windows we only support constant transparency and masking, so to achieve this effect, you can do one out of two things:
- Extract the transparent areas from the image as a bitmap and set this as the widget mask. This will not allow you to have partially transparent areas.
- If you want to show a QPixmap http://doc.qt.io/qt-5/qpixmap.html with an alpha as your splash screen, then you
can use this approach which is slightly less efficient. You need to figure out the geometry of your splashscreen and use QPixmap::grabWindow() http://doc.qt.io/qt-5/qpixmap.html#grabWindow to fetch this area into a QPixmap. Then take your pixmap and blend it on top of the grabbed pixmap. The resulting pixmap you can set as the widget pixmap.
#include <QtWidgets>
class Widget : public QWidget
{
public:
Widget()
{
setWindowFlags(Qt::FramelessWindowHint);
transparentPixmap = QPixmap("pixmap with an alpha");
desktopBackground= QPixmap::grabWindow(0, x(), y(), width(),height());
}
void paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.drawPixmap(0, 0, desktopBackground);
painter.drawPixmap(0,0, transparentPixmap );
}
void resizeEvent(QResizeEvent *event)
{
setWindowOpacity(0.0);
desktopBackground= QPixmap::grabWindow(0, x(), y(), width(),height());
setWindowOpacity(1.0);
update();
}
private:
QPixmap desktopBackground;
QPixmap transparentPixmap;
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
Widget box;
box.resize(255, 255);
box.show();
return app.exec();
}
How can I do multiselection in a QCalendarWidget?
There is no direct API for doing multi selection in a QCalendarWidget http://doc.qt.io/qt-5/qcalendarwidget.html. What you can do however is to install an event filter on the viewport of the QTableView http://doc.qt.io/qt-5/qtableview.html which is used by the QCalendarWidget and check to see if the Shift modifier is pressed and if so select the relevant QModelIndexes http://doc.qt.io/qt-5/qmodelindex.html. The example below demonstrates how this can be done. Note that the example will need some tweaking if you want to use it. It does for example only work when selecting forwards, not when selecting backwards.
#include <QtWidgets>
class CalendarWidget : public QCalendarWidget {
Q_OBJECT
public:
CalendarWidget(QWidget *parent = nullptr) : QCalendarWidget(parent)
{
view = qFindChild<QTableView *>(this);
view->viewport()->installEventFilter(this);
}
bool eventFilter(QObject *obj, QEvent *event)
{
if (obj->parent() && obj->parent() == view) {
if (event->type() == QEvent::MouseButtonPress ||
event->type() == QEvent::MouseButtonRelease) {
QMouseEvent *me = static_cast<QMouseEvent*>(event);
QPoint pos = me->pos();
if (event->type() == QEvent::MouseButtonPress &&
!(me->modifiers() & Qt::ShiftModifier)) {
QModelIndex idx = view->indexAt(pos);
if (idx.row() != 0 && idx.column() != 0)
startIndex = idx;
} else if (event->type() == QEvent::MouseButtonRelease &&
me->modifiers() & Qt::ShiftModifier) {
QModelIndex idx = view->indexAt(pos);
if (idx.row() != 0 && idx.column() != 0)
endIndex = idx;
else
return false;
if (!startIndex.isValid())
startIndex =
view->selectionModel()->selectedIndexes().first();
endIndex = view->indexAt(pos);
int rowStart = startIndex.row();
int rowEnd = endIndex.row();
int colStart = startIndex.column();
int colEnd = endIndex.column();
QItemSelection sel;
for (int i=rowStart;i<=rowEnd;i++) {
if (i == rowStart && i != rowEnd) {
for (int j=colStart;
j<view->model()->columnCount();j++)
view->selectionModel()->select(
view->model()->index(i, j),
QItemSelectionModel::Select);
} else if (i == rowEnd) {
int start = (i == rowStart) ? colStart : 1;
for (int j = start;j<colEnd;j++)
view->selectionModel()->select(
view->model()->index(i, j),
QItemSelectionModel::Select);
} else {
for (int j=1;j<view->model()->columnCount();j++)
view->selectionModel()->select(
view->model()->index(i, j),
QItemSelectionModel::Select);
}
}
view->selectionModel()->select(endIndex,
QItemSelectionModel::Select);
return true;
}
}
return false;
} else {
return QCalendarWidget::eventFilter(obj, event);
}
}
private:
QTableView *view;
QPersistentModelIndex startIndex;
QPersistentModelIndex endIndex;
};
#include "main.moc"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
CalendarWidget calendar;
calendar.show();
return app.exec();
}
Is it possible to install and run Qt for Embedded Linux on a headless machine?
Yes. Remote display is possible by using Qt for Embedded Linux's VNC drivers.
Yes. Qt for Embedded Linux supports the following:
- Tab groups
- Alt-F4
- Alt-Tab
- Shift-Alt-Tab
- arrow (for radio button groups)
- spacebar (for radio button or checkbox select)
- Alt-spacebar (for window menu)
- Shift-Ctrl-arrow and Shift-arrow (to highlight characters)-
- Windows-key-D (minimize all windows)
- Esc (remove dialog or menu)
Does the Qt for Embedded Linux windowing system support standard window operations?
Qt for Embedded Linux supports the following operations:
- minimize
- maximize/restore
- close
- resize by click-n-drag (horizontal, vertical, or both)
- reposition by click-n-drag
- select the active window by clicking on it
How does Qt for Embedded Linux access the display?
Qt for Embedded Linux comes with some graphics drivers, but most of Qt for Embedded Linux applications access the Linux video frame buffer directly. Specific accelerated drivers can also be implemented in Qt for Embedded Linux, as plug-in, to improve performances. Such drivers access the graphics hardware directly to utilize any available hardware acceleration of graphics operations.
Why can't I debug the Qt sources when using the Qt SDK?
When selecting the default option when installing the Qt SDK, the sources are not included in the installation. You need to choose the custom option and ensure you have checked the install the Qt sources options when running the installer, otherwise they will not be provided and you will run in to this problem. As an alternative, you can install the sources later using the SDK maintenance tool and then select Package manager > Miscellanous > Qt Sources.
Does Qt for Embedded Linux make any assumptions about keyboard and mouse events or can we use our own drivers?
Qt for Embedded Linux has a plug-in framework for mouse and keyboard drivers. Some drivers are already supported (linuxtp, intellimouse, mouseman, tslib etc.). Individual drivers can easily be written. Qt for Embedded Linux can also connect to kernel drivers for mouse and keyboard over sockets.
How can I change the row height of a QTreeView?
The delegate's sizeHint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#sizeHint is used to determine the row height of the QTreeView, so you need to reimplement the delegate's sizeHint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#sizeHint to return the size you want.
The following example illustrates how this can be done:
#include <QtWidgets>
class ItemDelegate : public QStyledItemDelegate
{
public:
using QStyledItemDelegate::QStyledItemDelegate;
QSize sizeHint (const QStyleOptionViewItem &option, const QModelIndex &index) const override
{
return QSize(50, 50);
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QTreeView view;
QStandardItemModel *model = new QStandardItemModel;
model->insertRows(0, 4);
model->insertColumns(0, 4);
for (int row = 0; row < 4; row++) {
for (int col = 0; col < 4; col++) {
QModelIndex index = model->index(row, col);
model->setData(index, QVariant((row+1) *(col+1)).toString());
}}
ItemDelegate *delegate = new ItemDelegate();
view.setModel(model);
view.setItemDelegate(delegate);
view.show();
return app.exec();
}
How can I avoid the underlining of links in a QTextBrowser ?
You can use style sheets for that. Here is an example:
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QTextBrowser browser;
QString sheet;
sheet.append("a[href="qt4-2-intro.html"] { text-decoration: underline; font-
style: italic; color: #00ff00; }");
sheet.append("a { text-decoration: none; }");
browser.document()->setDefaultStyleSheet(sheet);
browser.setSource(QUrl("index.html"));
browser.show();
return app.exec();
}
If you start this example with 'index.html' taken from the Qt documentation all the links will have their underline removed (no text decoration) and the link that points to the Qt 4.2 Intro will be underlined, italic and show up in green
See also: http://www.w3.org/TR/CSS21/selector.html
for the list of supported CSS selectors.
Yes. This can this be done with Qt for Embedded Linux. It is also possible to expose a hidden toolbar at the top of the screen as one typically sees in these fullscreen modes.
What kind of touch screen / touch panel support does Qt for Embedded Linux have?
Qt for Embedded Linux supports several touch screen variants, including support for Linux Touch
Panel and tslib. Qt for Embedded Linux has a touch screen driver plug-in framework for implementing individual drivers.
How can I add tooltips to a QComboBox?
When setting tooltips for the individual items in a QComboBox http://doc.qt.io/qt-5/qcombobox.html you need to use the setItemData() http://doc.qt.io/qt-5/qcombobox.html#setItemData) function and specify the string you want to use for the tooltip specifying the ToolTipRole as the role for the data. For example:
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication a(argc, argv);
QComboBox box(0);
box.addItem("Item One");
box.setItemData(0, "This is a tooltip for item one", Qt::ToolTipRole);
box.addItem("Item Two");
box.setItemData(1, "This is a tooltip for item two", Qt::ToolTipRole);
box.addItem("Item Thee");
box.setItemData(2, "This is a tooltip for item three", Qt::ToolTipRole);
box.show();
return a.exec();
}
How can I translate the OK and Cancel buttons when using the static QMessageBox functions?
The OK and Cancel text for the buttons is part of the Qt source code. For more information on how to translate the Qt strings into your own language then look at lconvert. All you need to do is load the Qt translation file in addition to your original .qm file(s) when you load up your translation file(s). For the OK and Cancel buttons you would need to translate their text in the QDialogButtonBox section.
The example below demonstrates how this can be done:
TEMPLATE = app SOURCES += main.cpp TRANSLATIONS = t1_fr.ts qt_fr.ts CONFIG += console
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication a(argc, argv);
QTranslator trans(0);
trans.load("t1_fr", ".");
QTranslator trans2(0);
trans2.load("qt_fr", ".");
a.installTranslator(&trans);
a.installTranslator(&trans2);
QMessageBox::warning(0, QObject::tr("Warning Title"),
QObject::tr("Warning Message"),
QMessageBox::Ok|QMessageBox::Cancel);
return a.exec();
}
Why doesn't Mac OS X respect carriage return?
On Mac OS X the idea of a new line is the same as on other unices. OS9 and below used carriage return. One decision we made with Qt was to follow the Unix convention on Mac OS X, therefore QTextStream (and Qt in general) does not know how to deal with carriage return. You should use new line instead.
How can I embed a widget with a titlebar inside a QGraphicsScene?
You can embed a widget with a titlebar inside a QGraphicsScene http://doc.qt.io/qt-5/qgraphicsscene.html by specifying the Qt::Window http://doc.qt.io/qt-5/qt.html#WindowType-enum flag to the QGraphicsProxyWidget http://doc.qt.io/qt-5/qgraphicsproxywidget.html or the QGraphicsWidget http://doc.qt.io/qt-5/qgraphicswidget.html.
See the following example for an illustration:
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QGraphicsScene scene;
#if 1
QGraphicsWidget *window = new QGraphicsWidget(0);
window->setWindowFlags(Qt::Window);
scene.addItem(window);
#else
QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget();
proxy->setWidget(new QMainWindow());
proxy->setWindowFlags(Qt::Window);
scene.addItem(proxy);
#endif
QGraphicsView view(&scene);
view.resize(600, 600);
view.show();
return app.exec();
}
How can I detect hover events on the tabs of a QTabWidget?
The tabs in QTabBar http://doc.qt.io/qt-5/qtabbar.html are not widgets per say, so it is not possible to get hold of them to check if they have received any events. Instead, you can check if the position of the event is positioned in the tab by using QTabBar::tabAt() http://doc.qt.io/qt-5/qtabbar.html#tabAt
The following example illustrates how this can be done:
#include <QtWidgets>
class TabWidget : public QTabWidget
{
public:
TabWidget()
{
setMouseTracking(true);
addTab(new QWidget(this), "first");
addTab(new QWidget(this), "second");
addTab(new QWidget(this), "third");
tabBar()->setMouseTracking(true);
}
void mouseMoveEvent ( QMouseEvent * event )
{
QTabBar *wid = tabBar();
if (wid && wid->tabAt(event->pos()) != -1)
qDebug() << "mouse hovering in tab " << wid->tabAt(event->pos());
return QTabWidget::mouseMoveEvent(event);
}
};
int main(int argc, char** argv)
{
QApplication app(argc, argv);
TabWidget window;
window.show();
return app.exec();
}
Errors using macdeployqt caused by old version of XCode.
If macdeployqt fails with an error containing lines similar to the following :
Log: Using install_name_tool:
Log: in calculator.app/Contents/Frameworks/QtGui.framework/Versions/4/QtGui
Log: change reference QtCore.framework/Versions/4/QtCore
Log: to @executable_path/../Frameworks/QtCore.framework/Versions/4/QtCore
ERROR: install_name_tool: for architecture x86_64 object: calculator.app/Contents/Frameworks/QtGui.framework/Versions/4/QtGui malformed object (unknown load command 5)
The reason could be that you are using an older version of XCode.
We have found that upgrading XCode on these machines fixes this problem.
I would like to know how I can build Qt on Solaris / HP-UX / AIX
Note that Solaris 9 is currently not supported !
See our Supported Platforms http://doc.qt.io/qt-5/supported-platforms.html
You should be able to build Qt on those platforms if you disable WebKit and JavaScriptCore entirely. Those platforms are not supported and tested upstream, therefore Webkit is not supported on these.
If you use the -no-script and -no-webkit configure flags, then things should be fine. The legacy Qt script implementation is now available as an add-on solution. See:
http://blog.qt.io/2009/11/23/qtscript-in-46/
How can I have several Qt versions installed under WINNT\system32?
In order for your Qt applications to pick up the correct version of Qt installed under system32, you can build Qt with a custom name. You can do this using the qtlibinfix http://doc.qt.io/qt-5/configure-options.html option i.e
configure -qtlibinfix customName
Then your different Qt applications should be able to pick up its custom Qt version from the system32 directory.
How can I set an empty default value in QSpinBox?
QSpinBox http://doc.qt.io/qt-5/qspinbox.html does not allow displaying an empty value by default. Support for an empty value can be added however by reimplementing textFromValue() http://doc.qt.io/qt-5/qspinbox.html#textFromValue and having it return an empty string under certain conditions. The example demonstrates this approach by returning the empty string instead of the minimum value.
#include <QtWidgets>
class SpinBox : public QSpinBox
{
Q_OBJECT
public:
SpinBox(QWidget *parent = nullptr)
: QSpinBox(parent)
{}
int valueFromText(const QString &text) const override
{
if (text.isEmpty())
return minimum();
return QSpinBox::valueFromText(text);
}
QString textFromValue(int v) const override
{
if (v == minimum())
return QString();
return QSpinBox::textFromValue(v);
}
};
#include "main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
SpinBox box;
box.show();
return app.exec();
}
How can I use one horizontal scrollbar to scroll several QGraphicsViews?
In order to use one scrollbar to scroll several views, you can put your views and a QScrollBar http://doc.qt.io/qt-5/qscrollbar.html inside a widget and connect the scrollbar's value changed signal to the setValue() http://doc.qt.io/qt-5/qabstractslider.html#value-prop slots of the hidden horizontal scrollbars. In addition the ranges need to be kept in sync, although you can easily change this if you want to make it a bit smarter. See the following example for a demonstration:
#include <QtWidgets>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr) : QWidget(parent)
{
QGraphicsScene *scene = new QGraphicsScene();
scene->addEllipse(QRectF(-100, -100, 300, 200), QPen(Qt::blue), QBrush(Qt::cyan));
QGraphicsView *view1 = new QGraphicsView(scene);
view1->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
QGraphicsView *view2 = new QGraphicsView(scene);
view2->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scrollbar = new QScrollBar(Qt::Horizontal, this);
QVBoxLayout *vertical = new QVBoxLayout(this);
QWidget *subWidget = new QWidget(this);
QHBoxLayout *layout = new QHBoxLayout(subWidget);
layout->addWidget(view1);
layout->addWidget(view2);
vertical->addWidget(subWidget);
vertical->addWidget(scrollbar);
scrollbar->setRange(view1->horizontalScrollBar()->minimum(), view1->horizontalScrollBar()->maximum());
connect(scrollbar, SIGNAL(valueChanged(int)), view1->horizontalScrollBar(), SLOT(setValue(int)));
connect(scrollbar, SIGNAL(valueChanged(int)), view2->horizontalScrollBar(), SLOT(setValue(int)));
connect(view1->horizontalScrollBar(), SIGNAL(rangeChanged(int, int)), this, SLOT(updateRange(int, int)));
}
public slots:
void updateRange(int min, int max)
{
scrollbar->setRange(min, max);
}
private:
QScrollBar *scrollbar;
};
#include "main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
Widget widget;
widget.show();
return app.exec();
}
How can I get webkit to load local resources referenced within html returned from a custom scheme?
When creating a custom network manager in order to support a custom protocol then webkit does not know that the custom scheme should be considered as a local scheme. Therefore its default security mechanism of preventing access to local resources (file:) from remote schemes is triggered because it thinks the custom protocol is a remote scheme. Therefore images for example, which are referenced via local files will not get loaded. In order to get around this, you can call QWebSecurityOrigin::addLocalScheme() http://doc.qt.io/qt-5/qwebsecurityorigin.html#addLocalScheme which adds the given scheme to the list of schemes that are considered equivalent to the file scheme.
How can I get a QStackedWidget to automatically switch size depending on the content of the page?
When having a QStackedWidget http://doc.qt.io/qt-5/qstackedwidget.html that contains pages that you want to display in different sizes, then it can adjust its size automatically when switching pages if you follow these steps:
- set the size policy of the invisible pages to ignored
- set the size policy of the page that is going to be visible to e.g preferred
- call adjustSize() http://doc.qt.io/qt-5/qwidget.html#adjustSize in order to adjust the size to the sizeHint() http://doc.qt.io/qt-5/4.7/qwidget.html#sizeHint-prop.
This article() http://doc.qt.io/qt-5/qq/qq06-qwidgetstack.html in Qt Quarterly demonstrates how this can be done. It is written for Qt 3, but the concept remains the same for Qt 4:
The example below illustrates how this can be done:
#include <QtWidgets>
class SubWidget : public QWidget
{
Q_OBJECT
public:
SubWidget(QWidget *parent) : QWidget(parent)
{
table = new QTableWidget(this);
table->setColumnCount(10);
table->setRowCount(10);
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(table);
}
QSize minimumSizeHint () const
{
int newWidth = 0;
int newHeight =0;
for (int i = 0; i < table->columnCount(); i++) {
newWidth+= table->columnWidth(i);
}
for (int y = 0; y < table->rowCount(); y++) {
newHeight+= table->rowHeight(1);
}
newWidth+= table->verticalHeader()->width() + 2 *table->frameWidth();
newHeight+= table->horizontalHeader()->height() +2 *table->frameWidth();
return QSize(newWidth, newHeight);
}
private:
QTableWidget *table;
};
class Widget : public QWidget
{
Q_OBJECT
public:
Widget() : QWidget()
{
QPushButton *firstButton = new QPushButton("Open second page", this);
QPushButton *secondButton = new QPushButton("Open first page", this);
stackWidget = new QStackedWidget(this);
SubWidget *firstPage = new SubWidget(stackWidget);
QWidget *secondPage = new QWidget(stackWidget);
QLineEdit *edit2 = new QLineEdit(secondPage);
QVBoxLayout *secondPageLayout = new QVBoxLayout(secondPage);
secondPageLayout->addWidget(edit2);
stackWidget->addWidget(firstPage);
stackWidget->addWidget(secondPage);
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(secondButton);
layout->addWidget(firstButton);
layout->addWidget(stackWidget);
connect(firstButton, SIGNAL(clicked()), this, SLOT(test1()));
connect(secondButton, SIGNAL(clicked()), this, SLOT(test2()));
}
public slots:
void test1()
{
changeCurrent(1);
}
void test2()
{
changeCurrent(0);
}
private:
void changeCurrent(int idx)
{
if (stackWidget->currentWidget() !=0) {
stackWidget->currentWidget()->setSizePolicy(QSizePolicy::Ignored,
QSizePolicy::Ignored);
}
stackWidget->setCurrentIndex(idx);
stackWidget->currentWidget()->setSizePolicy(QSizePolicy::Expanding,
QSizePolicy::Expanding);
adjustSize();
}
QStackedWidget *stackWidget;
};
#include "main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
Widget window;
window.show();
return app.exec();
}
How can I modify the color of some of the rows in my QTableWidget ?
You can achieve this by reimplementing the delegate's paint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#paint function and then modifying the palette for the rows you want. See the following example:
#include <QtWidgets>
class ItemDelegate: public QStyledItemDelegate
{
public:
using QStyledItemDelegate::QStyledItemDelegate;
void paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
{
QPalette pal = option.palette;
QStyleOptionViewItem viewOption(option);
if(index.row() == 0) {
viewOption.palette.setColor(QPalette::HighlightedText, Qt::red);
} else if (index.row() == 5) {
viewOption.palette.setColor(QPalette::HighlightedText, Qt::blue);
} else {
viewOption.palette.setColor(QPalette::HighlightedText, Qt::white);
}
QStyledItemDelegate::paint(painter, viewOption, index);
}
};
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QTableWidget table(10,10);
table.setItemDelegate(new ItemDelegate());
QTableWidgetItem *item1= new QTableWidgetItem();
item1->setText("item 1");
table.setItem(0, 0, item1);
table.show();
return app.exec();
}
How can I get hold of a cell widget's row?
The widgets set on the cells have nothing to do with the contents of the table, so calling currentRow() http://doc.qt.io/qt-5/qtablewidget.html#currentRow will return -1 when such cells are being edited. In order to get row or column information for a cell widget that is being edited, you can get hold of the widget using QApplication::focusWidget() http://doc.qt.io/qt-5/qapplication.html#focusWidget and get the model index using QTableView::indexAt() http://doc.qt.io/qt-5/qtableview.html#indexAt. Then it is easy to get the row or column information from the model index by calling row() http://doc.qt.io/qt-5/qmodelindex.html#row or column() http://doc.qt.io/qt-5/qmodelindex.html#column on it.
The following example illustrates how this can be done:
#include <QtWidgets>
class TableWidget : public QTableWidget
{
Q_OBJECT
public:
TableWidget()
{
edit = new QLineEdit(this);
setColumnCount(5);
setRowCount(5);
setCellWidget(4,1, edit);
connect(edit, SIGNAL(textChanged(const QString)), this, SLOT(test1(const QString)));
}
public slots:
void test1(const QString &text)
{
QWidget *wid = QApplication::focusWidget();
if (wid) {
QModelIndex index = indexAt(wid->pos());
qDebug() << index.row();
}
}
private:
QLineEdit *edit;
};
#include "main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
TableWidget window;
window.show();
return app.exec();
}
Loading a Sql driver from a customized location
By default the sql driver is loaded from a ��lugins��subfolder of a library path.
If you want to load a sql driver from your own location (like c:\MyApplicationFolder) then you need to use a QPluginLoader and cast the plugin to a QSqlDriverPlugin.
Following is an example of how to load an OCI driver:
QPluginLoader loader("C:\\MyApplicationFolder\\qsqloci4.dll");
QObject *plugin = loader.instance();
if (!plugin)
return;
QSqlDriverPlugin *sqlPlugin = qobject_cast<QSqlDriverPlugin *>(plugin);
if (!sqlPlugin ) {
QMessageBox::warning(this, "SQL plugin", "Loading failed", QMessageBox::Ok);
return;
}
QSqlDatabase db = QSqlDatabase::addDatabase(ociDriver->create("QOCI"));
How can I detect in the .pro file if I am compiling on a 32 bit or a 64 bit platform?
You can use QMAKE_HOST.arch for this. The QMAKE_HOST variable expresses host information about the machine running qmake and QMAKE_HOST.arch allows you to determine the target architecture. You can use it as follows:
win32-g++:contains(QMAKE_HOST.arch, x86_64):{
do something
}
How can I disable autoscroll when selecting a partially displayed column in a QTreeView?
When clicking on a partially displayed column in a QTreeView http://doc.qt.io/qt-5/qtreeview.html, the view will scroll to display the complete content of the column. If you want to disable this behavior, then you can subclass your view and reimplement scrollTo() http://doc.qt.io/qt-5/qtreeview.html#scrollTo to reset the value of the horizontal scrollbar to the value it had before the scroll.
The following example demonstrates how this can be done:
#include <QtWidgets>
class TreeWidget : public QTreeWidget
{
public:
TreeWidget()
{
QTreeWidgetItem *tmp = new QTreeWidgetItem(this);
tmp->setText(0, tr("This is the very very first column"));
tmp->setText(1, tr("This is the very very secondary column"));
QTreeWidgetItem *item2 = new QTreeWidgetItem(this);
item2->setText(0, tr("This is the very very first column"));
item2->setText(1, tr("This is the very very second column"));
QTreeWidgetItem *item3 = new QTreeWidgetItem(this);
item3->setText(0, tr("This is the very very first column"));
item3->setText(1, tr("This is the very very second column"));
QTreeWidgetItem *item4 = new QTreeWidgetItem(this);
item4->setText(0, tr("This is the very very first column"));
item4->setText(1, tr("This is the very very second column"));
}
void scrollTo ( const QModelIndex & index, ScrollHint hint = EnsureVisible )
{
int myValue = horizontalScrollBar()->value();
QTreeWidget::scrollTo(index, hint);
horizontalScrollBar()->setValue(myValue);
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
TreeWidget box;
box.setColumnCount(2);
box.resize(150,200);
box.show();
return app.exec();
}
Can Qt Assistant be modified and redistributed with my application?
Qt Assistant can be modified and redistributed with your application, however the only constraint is that you do not modify the About boxes in Qt Assistant. They must still be available in their existing locations and contain the same text. For further information, consult the LICENSE file distributed with the package.
Note that you cannot distribute any of the documentation provided with Qt, this includes the Qt Assistant documentation, so you will need to provide your own if you want to provide documentation on how to use Qt Assistant.
How can I drag from e.g a QListWidget and drop in an editable QTableView?
In order to enable dragging from the QListWidget, you need to reimplement dragEnterEvent() http://doc.qt.io/qt-5/qabstractitemview.html#dragEnterEvent and dragMoveEvent() http://doc.qt.io/qt-5/qabstractitemview.html#dragMoveEvent to accept the event. In addition you need to set setDragEnabled() http://doc.qt.io/qt-5/qabstractitemview.html#dragEnabled-prop to true to enable dragging of the view's items.
For the QTableView you need to set setAcceptDrops() http://doc.qt.io/qt-5/qwidget.html#acceptDrops-prop to true in order to allow drops and then set a model on the view that has reimplemented setData() http://doc.qt.io/qt-5/qabstractitemmodel.html#setData and flags() http://doc.qt.io/qt-5/qabstractitemmodel.html#flags to allow editing of the model.
The example below illustrates how this can be implemented:
#include <QtCore>
class ListWidget : public QListWidget
{
public:
ListWidget(QWidget *parent);
protected:
void dragEnterEvent(QDragEnterEvent *e)
{
e->accept();
}
void dragMoveEvent(QDragMoveEvent *e)
{
e->accept();
}
};
ListWidget::ListWidget(QWidget *parent) : QListWidget(parent)
{
addItem("Zero");
addItem("First");
addItem("Second");
addItem("Third");
addItem("Fourth");
// The tree supports dragging of its own items
setDragEnabled(true);
}
class DragModel : public QAbstractTableModel
{
public:
DragModel(QObject *parent)
{
QStringList firstRow;
QStringList secondRow;
for (int i = 0; i < 5; i++ ) {
firstRow.insert(i,"Row " + QString::number(i+1));
secondRow.insert(i,"Row " + QString::number(i+1));
}
stringList << firstRow << secondRow;
}
// Returns the number of rows
int rowCount (const QModelIndex &parent = QModelIndex()) const
{
return 2;
}
// Returns the number of columns
int columnCount(const QModelIndex &parent = QModelIndex()) const
{
return 5;
}
// Returns an appropriate value for the requested data.
// If the view requests an invalid index or if the role is not
// Qt::DisplayRole, an invalid variant is returned.
// Any valid index that corresponds to a string for the index's column and row in
// the stringlist is returned
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const
{
if (!index.isValid())
return QVariant();
if (role != Qt::DisplayRole)
return QVariant();
QStringList list = (QStringList)stringList.at(index.row());
return list.at(index.column());
}
// Changes an item in the string list, but only if the following conditions
// are met:
// * The index supplied is valid.
// * The index corresponds to an item to be shown in a view.
// * The role associated with rendering data is specified.
// The dataChanged() signal is emitted if the item is changed.
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole)
{
if (index.isValid() && role == Qt::EditRole) {
// Set the data in the current cell to be value
stringList[index.row()].replace(index.column(), value.toString());
// We only want to change the data for the current cell
emit dataChanged(index, index);
return true;
}
return true;
}
// Return the default flags for this index in addition to flags
// that will accept drops and editing
Qt::ItemFlags flags(const QModelIndex & index) const
{
return QAbstractItemModel::flags(index) | Qt::ItemIsDropEnabled | Qt::ItemIsEditable;
}
private:
// Each row will consist of a list of strings
QList<QStringList> stringList;
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QWidget widget;
QHBoxLayout *layout = new QHBoxLayout(&widget);
ListWidget *listWidget = new ListWidget(&widget);
QTableView *tableView = new QTableView(&widget);
DragModel *model = new DragModel(tableView);
tableView->setModel(model);
// The table view can accept drops
tableView->setAcceptDrops(true);
layout->addWidget(listWidget);
layout->addWidget(tableView);
widget.show();
return app.exec();
}
How can I build 64 bit Qt on a 32 bit system ?
If you want to build Qt as 64 bit, then you will first have to build the tools that Qt uses as 32 bit then the rest of the Qt libraries can be built in 64bit mode to enable you to build a 64bit version of your application.
The following steps should build everything correctly (using 32bit cp to signify a 32bit Visual Studio command prompt and 64bit cp to signify a 64bit Visual Studio command prompt):
- 32bit cp: Run configure with the options you want
- 32bit cp: cd src\tools && nmake (note this will fail at the uic3 step, this is fine)
- 64bit cp: cd src && nmake (note this will fail at the uic3 step, again this is fine)
- 64bit cp: cd src\tools\uic3 && qmake
- 64bit cp: cd src && nmake
Bear in mind that this means you cannot use uic3 as part of your build process because of the fact it links against a 64bit library. Also note that you will not be able to run any of the applications you create with the 64 bit built Qt. You will have to deploy them to a 64 bit machine to run them.
How can I convert a QString to char* and vice versa?
In order to convert a QString http://doc.qt.io/qt-5/qstring.html to a char*, then you first need to get a local8Bit representation of the string by calling toLocal8Bit() http://doc.qt.io/qt-5/qstring.html#toLocal8Bit on it which will return a QByteArray http://doc.qt.io/qt-5/qbytearray.html. Then call data() http://doc.qt.io/qt-5/qbytearray.html#data on the QByteArray to get a pointer to the data stored in the byte array.
See the following example for a demonstration:
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QString str1 = "Test";
QByteArray ba = str1.toLocal8Bit();
const char *c_str2 = ba.data();
printf("str2: %s", c_str2);
return app.exec();
}
Note that it is necessary to store the bytearray before you call data() on it, a call like the following
const char *c_str2 = str2.toLocal8Bit().data();
will make the application crash as the QByteArray has not been stored and hence no longer exists
To convert a char* to a QString you can use the QString constructor that takes a QLatin1String http://doc.qt.io/qt-5/qlatin1string.html to ensure the locale encoded string is correct with fromLocal8Bit() http://doc.qt.io/qt-5/qstring.html#fromLocal8Bit, e.g:
QString string = QString(QLatin1String(c_str2));
QString string = QString::fromLocal8Bit(c_str2);
In addition, if you want to just print out the string then you can use qPrintable() http://doc.qt.io/qt-5/qtglobal.html#qPrintable as a quick means to do this without having to convert to a char *. For example:
printf("str2: %s", qPrintable(str1));
How can I programatically find out which rows/items are visible in my view ?
Qt does not support retrieving the actual visible items in the viewport, you will have to calculate this yourself by listening to the valueChanged() http://doc.qt.io/qt-5/qabstractslider.html#valueChanged signal of the scrollbar to get the topmost row/item.
To get the bottom row, you can pass in the height of the view to QHeaderView::visualIndexAt() http://doc.qt.io/qt-5/qheaderview.html#visualIndexAt.
Qt supports two ways of scrolling, a pixel-based way and also an item-based way. Using the item-based http://doc.qt.io/qt-5/qabstractitemview.html#ScrollMode-enum way will make the calculation easier.
The following example demonstrates how this can be done:
#include <QtWidgets>
class TableWidget : public QTableWidget
{
Q_OBJECT
public:
TableWidget() : QTableWidget()
{
setColumnCount(100);
setRowCount(100);
setHorizontalScrollMode(QAbstractItemView::ScrollPerItem);
setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
connect(horizontalScrollBar(), SIGNAL(valueChanged(int)),
this, SLOT(outputColumns(int)));
connect(verticalScrollBar(), SIGNAL(valueChanged(int)),
this, SLOT(outputRows(int)));
}
public slots:
void outputColumns(int columns)
{
qDebug() << "Leftmost column" << columns;
int right = horizontalHeader()->visualIndexAt(width());
qDebug() << "Rightmost row" << right;
}
void outputRows(int rows)
{
qDebug() << "Top row" << rows;
int left = verticalHeader()->visualIndexAt(height());
qDebug() << "Bottom row" << left;
}
};
#include "main.moc"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
TableWidget table;
table.show();
return app.exec();
}
How do I create a sln from a SUBDIRS template?
All you need to do is:
qmake -tp vc
on the pro file and it will create a solution file for you.
When setting a global color group on my Mac everything goes black. What is the problem?
The order of initialization of global objects is not defined, but in any case comes before any code in functions is executed. This means that the QColorGroup object you create is actually created before QApplication has been created, and since the QApplication constructor takes care of reading all the values from the system setting this creates an invalid color group, and potentially has nasty side effects (this largely depends on the compiler used).
You should avoid global objects of non POD-type (i.e. any type with a constructor).
How to minimize memory footprint in Qt for Embedded Linux?
There's no single magical step that can reduce the memory footprint, but there are several things you might wish to consider. One is the use of more aggressive optimization. The other is to use the following flags during configuration:
-no-stl
-no-exceptions
To add the -o3 as a compiler option is pretty straightforward:
In the .pro file, add the following lines:
QMAKE_CFLAGS_DEBUG +=o3
QMAKE_CXXFLAGS_DEBUG +=o3
You should use RELEASE instead of debug in your release version.
Also make sure you remove unnecessary options from your configuration. You should remove any features that you will not use in your final applications.
Who implements the antialiasing? You or the platform?
This depends on the engine:
- QImage http://doc.qt.io/qt-5/qimage.html: implemented in Qt
- QWidget http://doc.qt.io/qt-5/qwidget.html: platform dependent, Qt on Windows, XRender on X11, CoreGraphics on Mac OS X
- QPixmap http://doc.qt.io/qt-5/qpixmap.html: same as QWidget
- QPrinter http://doc.qt.io/qt-5/qprinter.html: does not have antialiasing because of high dpi.
- PDF: antialiasing is done by the viewer
- OpenGL http://doc.qt.io/qt-5/qtopengl.html: implemented in OpenGL based on supersampling
What function can I replace the QPaintDeivce::handle() function from Qt 3 in Qt 4 with?
In Qt 3 all of the paint devices were tied one-to-one with an underlying object. QPixmap http://doc.qt.io/qt-5/qpixmap.html was a Windows HBITMAP or X11 pixmap for example. This tight connection between native and Qt classes no longer exists in Qt 4, but we have created mappings in the places where connections do exist. Toplevel widgets have a winId() http://doc.qt.io/qt-5/qwidget.html#winId for example and QPixmap a to/ fromWinHBITMAP() http://doc.qt.io/qt-5/qpixmap.html#fromWinHBITMAP, QWidget has getDc() http://doc.qt.io/qt-5/qwidget.html#getDC and releaseDC() http://doc.qt.io/qt-5/qwidget.html#releaseDC etc.
So the new functions are spread over several classes and in most cases you could simply use one of the new alternatives. If you want to convert between Windows bitmaps and our pixmaps for example then you could use QPixmap::fromWinHBITMAP().
If you wish to use GDI directly on the widget then this is more tricky since all drawing happens in the backingstore, so you would also have to draw with GDI on it. That could be achieved in the paintEvent() http://doc.qt.io/qt-5/qwidget.html#paintEvent by calling
painter.paintEngine()->getDC()
and then later releaseDC().
Why does the pushbutton suddenly become square on the Mac when it gets down to a certain size?
This is intentional and a compromise.The main idea is that at a certain size, the elliptical pushbuttons start looking very bad. We went with a bevel button because this was the best solution at the time, mainly because people are not constantly resizing their buttons and it preserves the font settings. If we were to use a mini button there we would have to change the widget's font and this would be disturbing, particularly for people who have a certain font set.
How can I keep the pixmap background at all times for flat buttons?
To keep the pixmap background all the time for flat buttons you need to set button's Button http://doc.qt.io/qt-5/qpalette.html#ColorRole-enum color role to be the pixmap. Note that changing the palette will not work for all styles, it will for example not work for the XP and MacStyle which are pixmap based. For these styles you will have to draw this yourself in the paint event or set a style that supports this on the button.
See the following example:
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
app.setStyle(new QWindowsStyle());
QPixmap pixmap(200, 200);
{
QPainter p(&pixmap);
p.fillRect(0, 0, 200, 200, QRadialGradient(100, 100, 100, 150, 150));
}
QWidget wid;
QPushButton *button = new QPushButton(&wid);
button->setText("Button");
button->setAutoFillBackground(true);
button->setFlat(true);
QPalette pal = button->palette();
pal.setBrush(button->backgroundRole(), pixmap);
pal.setBrush(QPalette::Button, pixmap);
button->setPalette(pal);
QVBoxLayout *layout = new QVBoxLayout(&wid);
layout->addWidget(button);
wid.show();
int ret = app.exec();
return ret;
}
How can I get rid of the focus rectangle for a QTextEdit in the motif style?
In order to get rid of the focus rectangle of a text edit, you need to subclass the QMotifStyle http://doc.qt.io/qt-5/qmotifstyle.html and reimplement drawControl() http://doc.qt.io/qt-5/qmotifstyle.html#drawControl to draw nothing when the control element is CE_FocusFrame http://doc.qt.io/qt-5/qstyle.html#ControlElement-enum.
The example below demonstrates how this can be done.
#include <QtWidgets>
class Style : public QMotifStyle
{
public:
Style() {}
void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const override
{
if (element == CE_FocusFrame)
return;
QMotifStyle::drawControl(element, option, painter, widget);
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
Style *s = new Style();
app.setStyle(s);
QWidget wid;
QPushButton *button = new QPushButton("text", &wid);
QTextEdit *edit = new QTextEdit(&wid);
QVBoxLayout *layout = new QVBoxLayout(&wid);
layout->addWidget(button);
layout->addWidget(edit);
wid.show();
return app.exec();
}
Can I resize a toplevel window to zero height and zero width?
This will depend upon the different window managers. Windows for example enforces your top level windows to have a minimum size, so it is not possible to resize them smaller than that size using Qt. Other window managers may allow this though, if you have given your window a minimumSizeHint() http://doc.qt.io/qt-5/qwidget.html#minimumSizeHint-prop of 0,0.
After installing a new Qt version, Designer crashes when it loads the plugins, what's wrong?
If you have had an earlier version of Qt installed, then it might be that your plugins have not been updated to the new Qt version. Go into the designer\plugins directory and rebuild all your Designer plugins and if you have created additional plugins then rebuild them too.
How can I easily create a Visual Studio project from my existing pro file
Simply run qmake as follows:
- qmake -tp vc**
Note that this will take the existing template setting and prepend vc to it, so it will create a valid Visual Studio project file regardless of the template you use. The only exception is the SUBDIRS template.
Is there a way to tell qmake to copy files into my application bundle (e.g. private frameworks, sound files, etc.)?
You can do this using QMAKE_BUNDLE_DATA. All you need to do is define your files and where you want to put them in the bundle. qmake will take care of the rest.
Here's an example where we add a framework to the bundle
# Rest of the .pro file
PRIVATE_FRAMEWORKS.files = /path/to/MyFramework.framework
PRIVATE_FRAMEWORKS.path = Contents/Frameworks
QMAKE_BUNDLE_DATA += PRIVATE_FRAMEWORKS
Which UML modelers can be used to perform reverse engineering on code written with Qt?
Qt does not provide a tool to help you with reverse engineering, but you can use Rational Rose, see:
http://www-306.ibm.com/software/awdtools/developer/technical/
Alternatively, you can use Umbrello from KDE, see:
http://uml.sourceforge.net/index.php
How does Qt pick a font for the application?
If you have not set a font for your application then the default font on your machine will be used, and the default font can be different on different machines. On Windows the default Windows font is used, on X11 the one in qtrc can be used. If a default font can't be found, then a font specified by Qt will be used.
In order to get the same font for all machines you should set a font for your application. Note that this font needs to be installed on the target machine. You can find information on this subject here:
http://doc.qt.io/qt-5/qfont.html
How can I make one of my toolbars appear on the right hand side of the topdock area?
There is no API for this, but you can play around with the size policies http://doc.qt.io/qt-5/qsizepolicy.html#Policy-enum to achieve what you want. See the following example:
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QMainWindow box;
QToolBar *toolBar = new QToolBar(&box);
QToolBar *toolBar2 = new QToolBar(&box);
toolBar->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
box.addToolBar(toolBar);
box.addToolBar(toolBar2);
QAction *action = toolBar->addAction(one);
QAction *action2 = toolBar2->addAction(right);
box.show();
return app.exec();
}
My custom widget appears as a grey rectangle in Designer. How can I fix this ?
The reason you only see a grey rectangle on the form is probably that you have not reimplemented domXml() http://doc.qt.io/qt-5/qdesignercustomwidgetinterface.html#domXml. You need to reimplement domXml() to at least specify the geometry property. See the following code for an example:
QString MyWidgetPlugin::domXml() const
{
return QString("<widget class=\"MyWidget\" name=\"MyWidget\"> "
" <property name=\"geometry\"> "
" <rect> "
" <x>0</x> "
" <y>0</y> "
" <width>100</width> "
" <height>100</height> "
" </rect> "
" </property> "
" </widget>");
}
See the documentation:
http://doc.qt.io/qt-5/qdesignercustomwidgetinterface.html#domXml
How can I run multiple instances of an application on Mac OS X ?
By default LaunchServices tries to make sure only one application is running at the time, but you can use QProcess to start others. See the documentation:
http://doc.qt.io/qt-5/qprocess.html#start
If you want to run multiple instances yourself, you can go into the bundle and type the name of the executable with an & at the end, this will allow you to open new instances.
Can I use your icons in my product?
The icons that are used in Qt's tools, i.e. Qt Designer http://doc.qt.io/qt-5/designer-manual.html, Qt Linguist http://doc.qt.io/qt-5/linguist-manual.html and Qt Assistant http://doc.qt.io/qt-5/assistant-manual.html are designed specifically by us. You have permission to use these in your own application, but you will need to add a notice that indicates that the copyright of the icons belong to The Qt Company.
How can I represent rich text in an itemview ?
The default delegate does not process or interpret HTML tags. The representation of the displayed information is handled at a very low level in the QAbstractItemDelegate http://doc.qt.io/qt-5/qabstractitemdelegate.html.
You could choose to implement this in a custom delegate, and then handle this in the QAbstractItemDelegate::paint() http://doc.qt.io/qt-5/qabstractitemdelegate.html#paint method. The example which illustrates this best is under ./examples/itemviews/pixelator http://doc.qt.io/qt-5/itemviews-pixelator.html in your Qt directory.
An alternative approach which is only feasible for small applications, is to actually set a style sheet on supported widgets on the QTableView http://doc.qt.io/qt-5/qtableview.html cells and style them accordingly.
How can I lay out a splitter so that one widget takes 2/3 of the space and another 1/3?
You can use QSplitter::setSizes() http://doc.qt.io/qt-5/qsplitter.html#setSizes for this.
QTextEdit gets a performance problem when filling up
QTextEdit http://doc.qt.io/qt-5/qtextedit.html is optimized for working with paragraphs and it is not designed for handling very large paragraphs. When having very long paragraphs you will run into a performance problem at some point, when this will happen depends on the speed of your machine, the font you are using etc. We are not planning to change this design since the users generally split their documents into paragraphs.
A solution to this problem can be to use a QPlainTextEdit http://doc.qt.io/qt-5/qplaintextedit.html instead of a QTextedit and set the maximum number of blocks using setMaximumBlockCount() http://doc.qt.io/qt-5/qplaintextedit.html#maximumBlockCount-prop.
Why doesn't OpenGL improve the performance of the chip demo?
The chip demo (as are most of the demos included with Qt) favors the raster engine since it draws many small shapes with minor state changes.
The GL engines are better at drawing larger shapes with gradients and alpha etc.
Too many small shapes and it suffers from overhead in the GL calls.
Whether or not OpenGL improves performance is down to the scenario in which you use it, but in most cases it is better. It just isn't for widget drawing nor for many of the Qt examples. If you had a picture gallery it would show off the performance improvements that OpenGL can bring.
How can I get rid of the white space outside the cells of my table?
If you don't need all of your header sections to be resizable, then you can achieve this by setting the resizeMode http://doc.qt.io/qt-5/qheaderview.html#ResizeMode-enum to stretch for one or more of the header sections:
table->horizontalHeader()->setResizeMode(4, QHeaderView::Stretch);
If you do need all of your header sections to be resizeable, then you need to reimplement the sizeHint() http://doc.qt.io/qt-5/qwidget.html#sizeHint-prop to account for the size of the cells and headers in the table.
Then you need to set this size to be the maximum size of the table. Since you allow resizing of the table's columns, you also need to connect a slot to the sectionResized http://doc.qt.io/qt-5/qheaderview.html#sectionResized signal and call setMaximumSize(sizeHint()) in there.
The example below demonstrates how this can be done for a toplevel table. If you need this to work for a table that is embedded into another widget, then you need to set the sizePolicy http://doc.qt.io/qt-5/qsizepolicy.html#Policy-enum to fixed, so that the sizeHint() is the only alternative.
#include <QtWidgets>
class TableWidget : public QTableWidget
{
Q_OBJECT
public:
TableWidget(int rows, int columns) : QTableWidget(rows, columns)
{
connect(horizontalHeader(), SIGNAL(sectionResized(int, int, int)), this, SLOT(sectionResized()));
connect(verticalHeader(), SIGNAL(sectionResized(int, int, int)), this, SLOT(sectionResized()));
}
QSize sizeHint () const
{
int newWidth = 0;
int newHeight =0;
for (int i = 0; i < columnCount(); i++) {
newWidth+= columnWidth(i);
}
for (int y = 0; y < rowCount(); y++) {
newHeight+= rowHeight(y);
}
newWidth+=verticalHeader()->width() + 2 *frameWidth();
newHeight+= horizontalHeader()->height() +2 *frameWidth();
return QSize(newWidth, newHeight);
}
public slots:
void sectionResized()
{
setMaximumSize(sizeHint());
}
};
#include "main.moc"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
TableWidget table(10,10);
table.setMaximumSize(table.sizeHint());
table.show();
table.resize(table.sizeHint());
return app.exec();
}
Do I have to delete my child widgets?
Ordinarily no. Child widgets will be automatically destroyed by the parent widget when that is destroyed. See the documentation of ~QObject() http://doc.qt.io/qt-5/qobject.html#dtor.QObject for details.
Is there a listing of the details of the changes in Qt 4 and what needs to be done to migrate from Qt 3.3.x to Qt 4?
You can find a list of the changes between Qt 3 and Qt 4 and what needs to be done when migrating from Qt 3 to Qt 4 by looking at the porting guide http://doc.qt.io/qt-5/porting4.html.
How do I export my form without changing the generated code?
Simply click on your form in Qt Designer and then go to the *Property Editor*. Expand the *name* property and you will be given an *export macro* property. In there you can specify the macro you use for specifying that the class should be exported.
Is there a simple way to change the coordinate system of QPainter so that the logical coordinates start from the lower left corner instead of the upper left corner?
There is no direct way to do this, but what you can do is to define your scale matrix and apply it to all primitives and positions instead of applying it to QPainter http://doc.qt.io/qt-5/qpainter.html itself. Alternatively, you can set the scale matrix on the painter and draw all your primitives, then unset the transformation and draw all your text.
How can I use plugins in a statically built Qt library in Qt 4?
When creating your own plugins, you need to use Q_EXPORT_PLUGIN2 http://doc.qt.io/qt-5/qtplugin.html#Q_EXPORT_PLUGIN2 in your plugin code to export the plugin and then Q_IMPORT_PLUGIN http://doc.qt.io/qt-5/qtplugin.html#Q_IMPORT_PLUGIN in your application to be able to use the plugin there. In addition you need to add
QTPLUGIN += pluginname
to your pro file.
See the documentation on QPluginLoader http://doc.qt.io/qt-5/qpluginloader.html.
When using Qt's predefined plugins, then you can find information on how touse them in a statically built Qt here http://doc.qt.io/qt-5/plugins-howto.html#static-plugins.
Is there a way I can get rid of the icon in the mdi child window's titlebar?
You can easily hide this icon by calling setWindowIcon() http://doc.qt.io/qt-5/qwidget.html#windowIcon-prop with a pixmap that has a transparent color, e.g:
QPixmap pix(16,16);
pix.fill(Qt::transparent);
child->setWindowIcon(QIcon(pix));
How can I find subitems in a QTreeWidget using findItems?
In order to find subitems in a QTreeWidget using findItems() http://doc.qt.io/qt-5/qtreewidget.html#findItems you need to specify the Qt::MatchRecursive http://doc.qt.io/qt-5/qt.html#MatchFlag-enum flag.
The following example illustrates how this can be done:
#include <QtWidgets>
int main( int argc, char** argv )
{
QApplication app( argc, argv );
QTreeWidget* treeWidget = new QTreeWidget;
treeWidget->setWindowTitle(Test);
treeWidget->setColumnCount(4);
QTreeWidgetItem* item = NULL;
for (int l=0; l<10; l++)
{
item = new QTreeWidgetItem(treeWidget);
item->setText(0, QString::number(l));
item->setText(1, QString::number(l));
item->setText(2, QString::number(l));
item->setText(3, test);
item->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsSelectable | Qt::ItemIsEnabled );
item->setCheckState(0, Qt::Unchecked);
}
QList<QTreeWidgetItem*> items = treeWidget->findItems(test,Qt::MatchExactly, 3);
int num = items.count();
qDebug(first time: %d, num);
for (int l=0; l<5; l++)
{
item = new QTreeWidgetItem(treeWidget->topLevelItem(4));
item->setText(0, QString::number(l));
item->setText(1, QString::number(l));
item->setText(2, QString::number(l));
item->setText(3, test);
item->setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsSelectable | Qt::ItemIsEnabled );
item->setCheckState(0, Qt::Unchecked);
}
treeWidget->show();
items = treeWidget->findItems(test, Qt::MatchExactly, 3);
items = treeWidget->findItems(test, Qt::MatchExactly | Qt::MatchRecursive, 3);
num = items.count();
qDebug(Second time: %d, num);
return app.exec();
}
Displaying a big pixmap or image does not work. How can this be fixed?
The windowing systems have some limitations in regards to the size of pixmaps that they are capable of rendering. The actual size of an image that is supported varies from machine to machine and depends on OS, graphics hardware, memory and other running applications. In general we recommend that one does not create pixmaps that are significantly larger than your screen. When you load a QImage http://doc.qt.io/qt-5/qimage.html and you want to draw this, it is implicitly converted to a pixmap so you are subject to this limitation.
To work around this, then if it is possible in your case, you can make your image smaller and load that one. If this is not an option, then you can split your big image into smaller chunks, say 1000 by 1000 pixels and draw the big image as adjacent parts of the big image.
Does QPainter support alpha channels with a QPrinter ?
It is highly system dependent and driver dependent if the printer supports alpha channel or not. The PostScript language does not have support for alpha channel so PostScript printers will not support this. Very few Windows printers also support alpha channels. There are however some solutions that can be used to emulate support for the alpha channel.
There are basically two algorithms you can use, one is to draw into a QPixmap http://doc.qt.io/qt-5/qpixmap.html#QPixmap-3 and then convert it to a QImage http://doc.qt.io/qt-5/qimage.html or directly to a QImage and draw it using QPainter::drawImage() http://doc.qt.io/qt-5/qpainter.html#drawImage passing either Qt::OrderedAlphaDither or Qt::DiffuseAlphaDither as the image conversion flags http://doc.qt.io/qt-5/qt.html#ImageConversionFlag-enum.
The second solution, which is useful if you have a complex scene, is to draw into an intermediate pixmap the size of your printer. However since images/pixmaps should not be larger than the screen size, you may have to split the drawing into multiple chunks, depending on the resolution of the printer.
void print()
{
QPrinter prn;
QPainter printer_painter(&prn);
QImage buffer(1000, 1000, QImage::Format_RGB32);
for (int y=0; y<prn.height(); y+=buffer.height()) {
for (int x=0; x<prn.width(); x+=buffer.width()) {
// Decide the render rectangle
QRect renderRect(x, y, buffer.width(), buffer.height());
// Clear the buffer
buffer.fill(0xffffffff);
// Render the buffer
QPainter image_painter(&buffer);
renderArea(&image_painter, renderRect);
image_painter.end();
// Put the rendered area on the printer.
printer_painter.drawImage(x, y, buffer);
}
}
}
What is the Qt Visual Studio add-in?
Qt Development Frameworks offers a seamless integration of Qt development tools for Microsoft Visual Studio 2005, 2008 and 2010. The Qt Visual Studio Add-in allows developers to use this standard development environment without having to worry about any Qt-related build steps or tools.
The main features of the add-in are:
- Wizards for creating new Qt projects and classes.
- Automated build setup for the Meta-Object Compiler(moc), the User Interface Compiler (uic), and the Resource Compiler (rcc).
- Import and export of Qt Project {.pro} and Project Include {.pri} files.
- Integrated Qt resource management.
- Integrated Qt documentation.
- Debugging extensions for Qt data types.
How can I trigger the redraw of a single QGraphicsItem?
You can easily call QGraphicsItem::update() http://doc.qt.io/qt-5/qgraphicsitem.html#update to only mark one item as dirty, and have this item redrawn.
I have a problem installing a Qt RPM/deb/etc. package.
You should contact the maintainer/creator of the package. These packages are not created/maintained by Qt Development Frameworks, only the .tar.gz source archive is.
Is a desktop simulation tool available?
Yes. The QVFb (Qt Virtual Framebuffer) allows Qt for Embedded Linux programs to be developed on your desktop machine, without switching between consoles and X11. It emulates a framebuffer using a shared memory region (the virtual frame buffer) and a utility to display the framebuffer in a window (QVFb).
In addition we provide Qt Simulator which allows you to quickly test and debug applications that target mobile devices. See the documentation on Qt Simulator http://doc.qt.io/qt-5/qtsimulator/simulator-description.html
How can I add a toolbar on a separate line?
What you can do is call insertToolBarBreak() http://doc.qt.io/qt-5/qmainwindow.html#insertToolBarBreak or addToolBarBreak() http://doc.qt.io/qt-5/qmainwindow.html#addToolBarBreak on the QMainWindow when adding the toolbars, this will have the effect of a new line in the toolbar area and therefore the next toolbars added will be on that new line.
How can I draw a pixmap with a background color after the pixmap is constructed from an image?
You can create a second pixmap, fill it with your background color, then draw the original pixmap on top. For example:
QPixmap filled(original.size());
QPainter paint(&filled);
paint.fillRect(0,0,original.width(), original.height(), backgroundColor);
paint.drawPixmap(0,0,original);
paint.end();
What is the program qtusagereporter?
qtusagereporter is a tool intended to monitor possible site / flexible licensing agreements.
qtusagereporter will try to contact Qt Development Frameworks to monitor usage when a special bit has been set in the Qt license contained in the Qt license file. This is to enable level of usage monitoring without installing dedicated servers on a customer's site.
If you do not have a special site licensing agreement withQt Development Frameworks, please feel free to delete the qtusagereporter file.
Why is not the MySql driver loaded when running my application?
You need to make sure that everything has the same configuration. Make sure you have built your application, Qt and your plugin with the same configuration (i.e. debug vs release). Also, you need to make sure you have set your PATH environment variable to find the relevant MySql dll so that it can be found when the application runs. Alternatively, you can put the MySql dll (e.g libmysql.dll) in the same folder as the Qt dlls in yourQtDirectory/bin.
How can I have my widget resize when I hide a child widget in a layout?
In order to have a widget that resizes when you hide a child widget that is in a layout you need to first invalidate the layout that contains the child widget that was hidden and then call adjustSize() http://doc.qt.io/qt-5/qwidget.html#adjustSize on the widget that contains that layout. If you have more parent widgets that contain that widget then you need to call adjustSize() on those too if you want to ensure that the top level widget adjusts to claim the space too. Something like:
widget->parentWidget()->layout()->invalidate();
QWidget *parent = widget->parentWidget();
while (parent) {
parent->adjustSize();
parent = parent->parentWidget();
}
where widget is the widget that has been hidden can be used generically to ensure that the top level widget adjusts to reclaim the space left by the hidden child widget.
How can I initialize the size of the central widget inside a QMainWindow?
You can initialize the size of the central widget by reimplementing its sizeHint() http://doc.qt.io/qt-5/qwidget.html#sizeHint-prop to the size you want it to have initially.
How can I prevent a window from becoming active when clicking on it on Windows?
There is no way in Qt to prevent a window from becoming active when the user interacts with it. This is controlled by the window manager and when we receive the different activation events in Qt, the activation has already happened.You might be able to solve that by using the native API.
How can i get hold of all of the visible items in my QListView?
In order to get hold of the visible items in a QListView http://doc.qt.io/qt-5/qlistview.html, then you can iterate over them using indexAt() http://doc.qt.io/qt-5/qlistview.html#indexAt. You can get hold of the first visible item using indexAt(QPoint(0, 0)), then in order to get the index at the next position then use visualRect() http://doc.qt.io/qt-5/qlistview.html#visualRect to find out what your next call to itemAt() should be. This position would be:
visualRect.y() + visualRect.height() + 1 effectively.
See the following example for an illustration:
#include <QtWidgets>
QList <QModelIndex>myList;
class ListView : public QListView
{
Q_OBJECT
public:
ListView()
{
QStringListModel *myModel = new QStringListModel(this);
QStringList list;
list << "a" << "b" <<"c" <<"d" <<"e" <<"f" <<"g" <<"h" <<"i" <<"j" <<"k";
myModel->setStringList(list);
setModel(myModel);
QTimer::singleShot(3000, this, SLOT(test1()));
}
public slots:
void test1()
{
QModelIndex firstIndex = indexAt(QPoint(0, 0));
if (firstIndex.isValid()) {
myList << firstIndex;
} while (viewport()->rect().contains(QPoint(0, visualRect(firstIndex).y() + visualRect(firstIndex).height() + 1 ))) {
firstIndex = indexAt(QPoint(0, visualRect(firstIndex).y() + visualRect(firstIndex).height() + 1 ));
myList << firstIndex;
}
qDebug() << myList.count() << "are visible";
}
};
#include "main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
ListView window;
window.resize(100, 50);
window.show();
return app.exec();
}
How can I print a widget?
You can use QPixmap::grabWidget() http://doc.qt.io/qt-5/qpixmap.html#grabWidget to get a pixmap representation of the widget. Since QPrinter is a paint device, you can open a painter on it directly and then draw this pixmap on to the printer.
The example below illustrates how this can be done:
#include <QtWidgets>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget()
{
QPushButton *button = new QPushButton(this);
button->setText(Print me);
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(button);
connect(button, SIGNAL( clicked() ), this, SLOT(print() ) );
}
public slots:
void print()
{
QPrinter *printer = new QPrinter;
QPrintDialog *printDialog = new QPrintDialog(printer, this);
if (printDialog->exec() == QDialog::Accepted) {
QPainter p(printer);
QPixmap pm = QPixmap::grabWidget(this);
p.drawPixmap(0, 0, pm);
}}};
#include main.moc"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
Widget box;
box.show();
return app.exec();
}
How can I get debug output from my Qt applications?
You can use qDebug() http://doc.qt.io/qt-5/qtglobal.html#qDebug and have the output on the console.
On Windows, applications run by default without a console, so output on stderr or stdout is not visible. You can add
CONFIG += console
to your .pro file (or modify the linker settings by changing /SUBSYSTEM:WINDOWS to /SUBSYSTEM:CONSOLE) to build a console-application, which runs attached to a console.
How to deal correctly with project files that should generate a debug and release build
You need to add the following to your .pro file:
CONFIG(debug, debug|release) { message(Debug build) } else { message(Release build) }
This means that it will ensure that the debug stuff is processed when generating the debug version of the Makefile, and in the other case which is the release version, that the release stuff is processed. This enables you to specify specific options for debug and release builds.
Note that you should use the *build_pass* variable to filter out messages, otherwise you will get messages when it creates the Makefile which will be the configuration specific makefile. When adding the *build_pass* variable in conjunction with the following scope
build_pass:CONFIG(debug, debug|release) {
message(Debug build)
}
else:build_pass {
message(Release build)
}
the output will be as follows:
Project MESSAGE: Debug bulid
Project MESSAGE: Release build
See the documentation: http://doc.qt.io/qt-5/qmake-function-reference.html
How do I make a Qt application make a 'beep' sound?
Call QApplication::beep() http://doc.troll.no/qapplication.html#beep
How can I instantiate new objects in my Qt Script code?
To make it possible to instantiate QObjects in your script code you first need to use the Q_SCRIPT_DECLARE_QMETAOBJECT http://doc.qt.io/qt-5/qscriptengine.html#Q_SCRIPT_DECLARE_QMETAOBJECTmacro to declare your QMetaObject. Then make your class available as a QScriptValue http://doc.qt.io/qt-5/qscriptvalue.html by calling QScriptEngine::scriptValueFromMetaObject() QScriptEngine::scriptValueFromMetaObject(). See the documentation:
See the following example for an illustration:
#include <QtScript>
#include <QtWidgets>
Q_SCRIPT_DECLARE_QMETAOBJECT(QLineEdit, QWidget*)
int main(int argc, char **argv)
{
QApplication app (argc, argv);
QScriptEngine engine;
QScriptValue lineEditClass = engine.scriptValueFromQMetaObject<QLineEdit>();
engine.globalObject().setProperty("QLineEdit", lineEditClass);
engine.evaluate("edit = new QLineEdit(0)");
engine.evaluate("edit.show()");
return app.exec();
}
lupdate has problems translating classes which are using a namespace, how can I solve this ?
C++ namespaces and the *using namespace* statement can confuse lupdate http://doc.qt.io/qt-5/linguist-manager.html#lupdate. lupdate will interpret MyClass::tr()as meaning just that, not as MyNamespace::MyClass::tr(), even if MyClass is defined in the MyNamespace namespace. Runtime translation of these strings will fail because of that. You can solve this issue by adding a TRANSLATOR http://doc.qt.io/qt-5/linguist-programmers.html#coping-with-c-namespaces comment at the beginning of the source files that use MyClass::tr().
See the following example for a demonstration:
/*
TRANSLATOR myNamespace::Menu
*/
#include <QtWidgets>
namespace myNamespace
{
class Menu : public QMenu
{
Q_OBJECT
public:
Menu(QWidget *parent) : QMenu(parent) {}
};
}
#include main.moc"
int main(int argc, char **argv) {
using namespace myNamespace;
QApplication a(argc, argv);
QTranslator trans(0);
trans.load(test_fr, .);
a.installTranslator(&trans);
QMainWindow w;
Menu menu(&w);
w.menuBar()->addMenu(&menu);
menu.setTitle(Menu::tr(File));
QAction *fileAction = new QAction(QObject::tr(Item), 0);
menu.addAction(fileAction);
w.show();
return a.exec();
}
How can I insert a checkbox into the header of my view?
Currently there is no API to insert widgets in the header, but you can paint the checkbox yourself in order to insert it into the header.
What you could do is to subclass QHeaderView, reimplement paintSection() http://doc.qt.io/qt-5/qheaderview.html#paintSection and then call drawPrimitive() http://doc.qt.io/qt-5/qstyle.html#drawPrimitivewith PE_IndicatorCheckBox in the section where you want to have this checkbox.
You would also need to reimplement the mousePressEvent() http://doc.qt.io/qt-5/qheaderview.html#mousePressEvent to detect when the checkbox is clicked, in order to paint the checked and unchecked states.
The example below illustrates how this can be done:
#include <QtWidgets>
class MyHeader : public QHeaderView
{
public:
MyHeader(Qt::Orientation orientation, QWidget * parent = nullptr) : QHeaderView(orientation, parent)
{}
protected:
void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
{
painter->save();
QHeaderView::paintSection(painter, rect, logicalIndex);
painter->restore();
if (logicalIndex == 0)
{
QStyleOptionButton option;
option.rect = QRect(10,10,10,10);
if (isOn)
option.state = QStyle::State_On;
else
option.state = QStyle::State_Off;
this->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter);
}
}
void mousePressEvent(QMouseEvent *event)
{
if (isOn)
isOn = false;
else
isOn = true;
this->update();
QHeaderView::mousePressEvent(event);
}
private:
bool isOn;
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QTableWidget table;
table.setRowCount(4);
table.setColumnCount(3);
MyHeader *myHeader = new MyHeader(Qt::Horizontal, &table);
table.setHorizontalHeader(myHeader);
table.show();
return app.exec();
}
To have all your other checkboxes checked, you could use the pressed() signal which should be fired from the mousePressEvent() http://doc.qt.io/qt-5/qheaderview.html#mousePressEvent and connect it to a custom slot where you set all your checkboxes checked or unchecked. See:
I would like to add some widgets to a QMessageBox. How can I do it?
QMessageBox http://doc.qt.io/qt-5/qmessagebox.html is just a convenience class and does not offer this functionality. You will have to construct your own dialog.
Do you have integration with Xcode ?
We have integration with Xcode. Typing the following line in a terminal will create an Xcode project:
qmake -spec macx-xcode project.pro
See the documentation http://doc.qt.io/qt-5/qtmac-as-native.html#development-tools:
Is it possible to change the language of Qt Assistant's GUI?
Qt Assistant will try to load a translation file called assistant_[locale].qm where [locale] is the locale as returned by QTextCodec::codecForlocale() http://doc.qt.io/qt-5/qtextcodec.html#codecForLocale. So if you have your locale set to German, then assistant will try to load a file called assistant_de.qm. Qt comes with .ts files for both French and German for Assistant, if you want a different language then you can use one of the existing files as a base and provide new translations using Linguist http://doc.qt.io/qt-5/linguist-manual.html.
Does Qt provide translations for the user visible strings of the widgets?
Qt provides translation files for French, German and Simplified Chinese in $QTDIR/translations. This directory also contains some additional unsupported translations which may be useful, see:
http://doc.qt.io/qt-5/internationalization.html
These files contain translations for all of the classes in Qt that contain user visible strings and you can add them to your .pro file and follow the standard translation procedure to use them. In addition Qt provides a template for translating to other languages in qt_untranslated.ts
See the documentation for more information:
http://doc.qt.io/qt-5/linguist-programmers.html
In addition we provide the lconvert tool which can be used to create an empty translation file so you can add your own translation for the Qt strings in a language that we don't provide for. To do this do:
lconvert --drop-translations -o qt_untranslated.ts qt_fr.ts
and then it will give you an empty translation file with the Qt strings ready to be translated.
We would like to use Linguist with an MFC application, without converting MFC to Qt. Is this possible?
Yes, but since the QObject http://doc.qt.io/qt-5/qobject.html class handles the translation, you will need to create a dll that has a function that basically calls QObject::tr() http://doc.qt.io/qt-5/qobject.html#tr and returns the result, making sure that you install the translators inside the code for the dll before using the function. You can use LoadLibrary in Windows API to load the library, then you just call the function via the dll.
Is there a way to remove the checkbox from a QTreeWidgetItem?
It is possible to remove the checbox from a QTreeWidgetItem http://doc.qt.io/qt-5/qtreewidgetitem.html that has the Qt::ItemIsUserCheckable http://doc.qt.io/qt-5/qt.html#ItemFlag-enum flag set, simply by calling setData() http://doc.qt.io/qt-5/qtreewidgetitem.html#setData on the item with an invalid QVariant http://doc.qt.io/qt-5/qvariant.html, e.g
item->setData(0, Qt::CheckStateRole, QVariant());
"Why doesn't my keyboard work after I have done an export QWS_KEYBOARD=/dev/tty?"
Try running the application without exporting QWS_KEYBOARD. The default value may be more appropriate than the value specified.
How can I implement my own proxy model that is more advanced than just sorting/filtering
In cases such as being able to hide the top level items but yet still see the children in an itemview is where you would want to use a proxy model. However QSortFilterProxyModel by itself is not adequate enough for the functionality needed.
Therefore you need to subclass QAbstractProxyModel instead which enables you to have full control over the way that the proxy model represents the items from the source model.
Attached to this solution is an example which shows how to handle this for a case where you want to hide all items except for the children (and grandchildren) of a particular item. Since we want to hide a top level item here, we need to actually ensure that the proxy items end up with new parents since the hierarchy has changed.
To do this in a way that makes it easy to manipulate the hierarchy in any way you want we have created two maps, one for the mapping of a source index to its corresponding proxy index. The other map is for mapping a proxy index to its new parent as represented by the original source index.
The reason behind mapping a proxy index to a parent index in the source model is to facilitate placing proxy indexes whereever we want them to be without having to be concerned with not having mapped the corresponding source index yet. Therefore we can easily map a child of an index in the source model to be the parent of that index in the proxy model.
The example uses QStandardItemModel to simplify things on the source model side, but you can change the model in use on the source model and just tweak the fixModel() function to handle your own model instead.
Mediaplayer demo program pauses before file is finished on embedded platform
This is most likely a problem with your phonon back end plugin. The officially supported back end is GStreamer, but the same applies to whatever back end you may be using.
You'll need to have a working GStreamer backend for Phonon to work correctly in Qt. To determine if GStreamer is working or not, try it directly by using the following command to determine if this is the case:
./gst-launch playbin uri=file:///home/joe/my-random-media-file.mpeg
Replacing the file path with an actual media file you know should work.
If you get any errors, or are unable to play your media file, then GStreamer is not installed or configured correctly, and this will need to be corrected before you can use it as a back end for phonon: http://gstreamer.freedesktop.org/documentation/
While it may be possible to build the GStreamer libraries and plugins for your hardware, that doesn't mean they will work well at all. Limitations on your hardware's ability to decode media will mean that playback could be limited to certain media types, and you may not be able to decode the media as fast as it needs to be played. Your hardware's SDK may contain a special build of the gstreamer libraries and plugins that take full advantage of the hardware available to your device, in which case this should be used for optimal GStreamer performance in Embedded Linux.
Again if you are not able to use GStreamer directly then you will not be able use it with Phonon. In this case you will need to contact your SDK provider or report a bug if needed to the GStreamer project: https://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer
How to improve graphics performance on X11
There are many factors that could be affecting the rendering of widgets under Qt.
A few things you can try in order of importance:-
1. Update your video/graphics driver to the latest. This usually involves downloading a binary installer from your graphics card vendor - e.g. Nvidia and installing this on your Linux box.
2. Run the application using the raster engine. This renders everything in software if you experiencing problems. You can use -graphicssystem raster to do this
3. Make sure your xrender libraries are up to date/installed.
4.See also the blogs series on Qt Graphics and Performance http://labs.trolltech.com/blogs/2010/01/11/qt-graphics-and-performance-the-cost-of-convenience.
How can I get QMAKE_POST_LINK to work with more than one command on Windows?
When using multiple commands with QMAKE_POST_LINK e.g.
QMAKE_POST_LINK += copy ..\file.lib ..\..\lib\
QMAKE_POST_LINK += copy ..\file2.lib ..\..\lib\
qmake tries to put them all on the same line, with the result that it fails to execute more than the first command.
The solution is to add $$escape_expand(\n\t) to the end of each QMAKE_POST_LINK entry.
This was tested and functions correctly with nmake using the Microsoft build environment.
How do I remove qtmain.lib from the Qt build?
To remove this, you can define *QMAKE_LIBS_QT_ENTRY* as empty in your .pro file like this:
QMAKE_LIBS_QT_ENTRY=
How can my stylesheet account for custom properties?
In order to account for custom properties in your stylesheet, you can use the Property Selector, see:
http://doc.qt.io/qt-5/stylesheet-syntax.html#selector-types http://doc.qt.io/qt-5/stylesheet-examples.html#customizing-using-dynamic-properties
If the value of the Qt property changes after the style sheet has been set, you will probably have to force a style sheet recomputation. This can be done by calling
style()->unpolish(theWidget);
style()->polish(theWidget);
Alternatively, you can unset the style sheet and set it again, but this is more expensive than the first solution.
The following example demonstrates how this can be done:
#include <QtWidgets>
class LineEdit : public QLineEdit
{
Q_OBJECT
public:
LineEdit(QWidget *wid) : QLineEdit(wid)
{
setProperty("theMaximum", false);
setStyleSheet("QLineEdit[theMaximum=\"true\"] {background-color: black}\
QLineEdit[theMaximum=\"false\"] {background-color: red}");
oldSheet = styleSheet();
QTimer::singleShot(3000, this, SLOT(test1()));
}
public slots:
void test1()
{
setProperty("theMaximum", true);
#if 1
style()->unpolish(this);
style()->polish(this);
#else
setStyleSheet(styleSheet());
#endif
}
private:
QString oldSheet;
};
#include "main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QWidget window;
QVBoxLayout *layout = new QVBoxLayout(&window);
layout->addWidget(new LineEdit(&window));
layout->addWidget(new QLabel("This is a LineEdit", &window));
window.show();
return app.exec();
}
How can I set headers for a QColumnView?
A custom header can be defined as a QHeaderView http://doc.qt.io/qt-5/qheaderview.html for each column, and the header text is supplied as the first item in the column (see example in the attachment).
In the QColumnView-model definition, we define the UserRole:
enum UserRole { HeaderRole = Qt::UserRole + 1 };
And in the model-declaration, we set the header-data on the custom HeaderRole:
QStandardItemModel * model = new QStandardItemModel();
QStandardItem * root = model->invisibleRootItem();
QStandardItem * item = new QStandardItem(QString("single %1").arg(i));
root->appendRow(item);
item->setData(tr("Header A 1"), CustomColumnView::HeaderRole);
The header is then painted in the reimplemented paintEvent() http://doc.qt.io/qt-5/qheaderview.html#paintEvent function of the QHeaderView class.
Why do I get an error when trying to set a model on QTableWidget?
QTableWidget http://doc.qt.io/qt-5/qtablewidget.html already comes with a model, so you can't set your own model on it. The reimplementation of QTableWidget::setModel() http://doc.qt.io/qt-5/qtableview.html#setModel in qtablewidget.cpp looks like this:
void QTableWidget::setModel(QAbstractItemModel * /*model*/)
{
Q_ASSERT(!"QTableWidget::setModel() - Changing the model of the QTableWidget is not allowed.");
}
So, if you want to use your own model, you need to use a QTableView http://doc.qt.io/qt-5/qtableview.html instead of the QTableWidget convenience class and set the model on that one.
How can I create editable headers in a QTableView?
QTableView http://doc.qt.io/qt-5/qtableview.html is not designed to have editable headers.
A solution to achieve this can be done with a QLineEdit http://doc.qt.io/qt-5/qlineedit.html. The idea is to create an edit box over the expected header section and make it behave like an usual cell when edited.
The example below illustrates this approach.
#include <QtWidgets>
class MyEditHeaderBox : public QLineEdit
{
Q_OBJECT
public:
MyEditHeaderBox(QWidget *parent =0)
: QLineEdit(parent)
{
QValidator *validator = new QDoubleValidator(this);
setValidator(validator);
setFocusPolicy(Qt::StrongFocus);
connect(this, SIGNAL(returnPressed()), this, SLOT(headerValue()));
}
void setLabelValue(Qt::Orientation orientation, int section, QString value)
{
setText(value);
curOrientation = orientation;
curSection = section;
}
protected slots:
void headerValue()
{
double value = text().toDouble();
emit updateHeader(value, curSection, curOrientation);
}
signals:
void updateHeader(double newValue, int section, Qt::Orientation o);
protected:
void keyPressEvent ( QKeyEvent * ev )
{
if (ev->key() == Qt::Key_Escape)
{
hide();
}
QLineEdit::keyPressEvent(ev);
}
void focusOutEvent ( QFocusEvent * event )
{
hide();
QLineEdit::focusOutEvent(event);
}
private:
Qt::Orientation curOrientation;
int curSection;
};
class MyMainWindow : public QMainWindow
{
Q_OBJECT
public:
MyMainWindow(QWidget *parent = nullptr)
: QMainWindow(parent), border(1)
{
view = new QTableView(this);
int nbPoints = 5;
model = new QStandardItemModel(nbPoints, nbPoints, this);
for (int r = 0; r < nbPoints; r++) {
for (int c = 0; c < nbPoints; c++) {
QStandardItem *item = new QStandardItem;
item->setData((r+1)*(c+1), Qt::DisplayRole);
model->setItem(r,c,item);
}
}
view->setModel(model);
le = new MyEditHeaderBox(this);
le->hide();
connect(view->horizontalHeader(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(xHeader(int)));
connect(view->verticalHeader(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(yHeader(int)));
setCentralWidget(view);
resize(550,300);
}
protected slots:
void xHeader(int section)
{
QPoint posHeaderX = QPoint(view->horizontalHeader()->geometry().x(), view->horizontalHeader()->geometry().y());
QPoint posView = this->pos() + QPoint(view->geometry().x(), view->geometry().y());
QPoint posSection = QPoint(view->horizontalHeader()->sectionPosition(section),-border);
showHeaderEditBox(section, Qt::Horizontal, QRect(posSection + posHeaderX , QSize(view->horizontalHeader()->sectionSize(section),view->horizontalHeader()->height())));
}
void yHeader(int section)
{
QPoint posHeaderY = QPoint(view->verticalHeader()->geometry().x(), view->verticalHeader()->geometry().y());
QPoint posView = this->pos() + QPoint(view->geometry().x(), view->geometry().y());
QPoint posSection = QPoint(0, view->verticalHeader()->sectionPosition(section)-border);
showHeaderEditBox(section, Qt::Vertical, QRect(posSection + posHeaderY, QSize(view->verticalHeader()->width(), view->verticalHeader()->sectionSize(section))));
}
void updateData(double newValue, int section, Qt::Orientation orientation)
{
view->model()->setHeaderData(section, orientation, newValue, Qt::DisplayRole);
le->hide();
}
protected:
void showHeaderEditBox(int section, Qt::Orientation orientation, QRect rectSection)
{
QString curValue = QVariant(view->model()->headerData(section, orientation, Qt::DisplayRole)).toString();
le->setGeometry(rectSection);
le->setLabelValue(orientation, section, curValue);
connect(le, SIGNAL(updateHeader(double,int,Qt::Orientation)), this, SLOT(updateData(double, int, Qt::Orientation)));
le->show();
le->setFocus();
le->selectAll();
}
private:
QTableView *view;
MyEditHeaderBox *le;
QStandardItemModel *model;
int border;
};
#include main.moc"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyMainWindow w;
w.show();
return a.exec();
}
How can the user be prevented from assigning to an undeclared variable in Qt Script?
To let the script engine know if an undeclared variable has been assigned, e.g in the following scenario:
function testClass()
{
this.someProperty = "test";
}
{
...
a_class = new myClass;
// the user incorrectly types the name of the variable and assigns it
a_class.SomeProperty = "assigned";
...
}
then you can use one of the following approaches.
- For QObjects http://doc.qt.io/qt-5/qobject.html then the most flexible approach would be to inherit from QScriptClass http://doc.qt.io/qt-5/qscriptclass.html so that you can control individual property access (read/write) yourself and e.g through an exception (QScriptContext::throwError() http://doc.qt.io/qt-5/qscriptcontext.html#throwError) when an incorrect property gets assigned.
- For QObjects, you can send along QScriptEngine::AutoCreateDynamicProperties() http://doc.qt.io/qt-5/qscriptengine.html#QObjectWrapOption-enum to newQObject() http://doc.qt.io/qt-5/qscriptengine.html#newObject, and listen for DynamicPropertyChangeEvent http://doc.qt.io/qt-5/qevent.html#Type-enum to find out when a property that does not exist in the metaobject gets assigned.
When using normal JS-objects it is not possible to detect this. In Ecmascript 5 there is a new function Object.seal() that makes it impossible to add new properties, but it is not supported by JavaScriptCore (the Javascript engine used by QtScript) yet.
Why is the fragment removed when using QDesktopServices::openUrl() to open a local file url with a fragment?
When opening a local file url with a fragment using QDesktopServices::openUrl() http://doc.qt.io/qt-5/qdesktopservices.html#openUrl then the fragment will not be shown due to a Windows limiation. A url containing the following string for example
.../extensionsystem-pluginview.html#pluginActivated"
will only display the
.../extensionsystem-pluginview.html
part. This is because Windows operates on files, and the fragment part (#pluginActivated in the example above) breaks the file name handling. Note that if you want to provide help documentation for your application, then the recommended way of providing help documentation with Qt is to use Qt Assistant http://doc.qt.io/qt-5/assistant-manual.html. Qt Assistant can use HTML source and make it viewable through assistant. The documentation http://doc.qt.io/qt-5/assistant-custom-help-viewer.html gives you more details.
How can I change the timeout period for a QToolTip?
The tooltip delay is currently hardcoded in the implementation of QApplication::notify() http://doc.qt.io/qt-5/qapplication.html#notify, so it is not possible to modify it directly. What you can do however is to send a QHelpEvent() http://doc.qt.io/qt-5/qhelpevent.html when the mouse hovers over your widget. Then you can show the tooltip using QToolTip::showText() http://doc.qt.io/qt-5/qtooltip.html#showText in your event handler and set up a timer that calls QToolTip::hideText() http://doc.qt.io/qt-5/qtooltip.html#hideText after the amount of time that you would like.
The example below illustrates how this can be done.
#include <QtWidgets>
class myButton :public QPushButton
{
Q_OBJECT
public:
myButton()
{
firstTime = true;
setMouseTracking(true);
}
bool event(QEvent *event)
{
if (event->type() == QEvent::ToolTip) {
firstTime = false;
QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
QString myToolTip=ToolTip for a button ;
QToolTip::showText(helpEvent->globalPos(),myToolTip );
QTimer::singleShot(4000, this, SLOT(testSlot()));
}
return QWidget::event(event);
}
void mouseMoveEvent(QMouseEvent *e)
{
QPushButton::mouseMoveEvent(e);
mousePosition = e->globalPos();
}
void leaveEvent(QEvent *myLeave)
{
QPushButton::leaveEvent(myLeave);
firstTime = true;
}
public slots:
void testSlot()
{
QToolTip::hideText();
}
public:
QPoint mousePosition;
bool firstTime;
};
class myWidget :public QWidget
{
Q_OBJECT
public:
myWidget(QWidget *parent=0):QWidget(parent)
{
but = new myButton;
but->setText(Hello:);
QVBoxLayout *layout = new QVBoxLayout;
setLayout(layout);
layout->addWidget(but);
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(myEventSender()));
timer->start(1000);
}
public slots:
void myEventSender()
{
if(but->underMouse() && but->firstTime)
{
QHelpEvent e(QEvent::ToolTip, but->pos(), but->mousePosition);
QApplication::sendEvent(but, &e);
}
}
public:
myButton *but;
};
#include main.moc"
int main(int argc,char *argv[])
{
QApplication app(argc,argv);
myWidget widget;
widget.show();
return app.exec();
}
How can I make my Qt application use wchar_t instead of wchar_t- ?
You need to configure Qt with wchar_t enabled as wchar_t- is enabled by default. So go to yourQtVersion/mkspecs/yourMkspec/qmake.conf and change the wchar_t- option to wchar_t and reconfigure and rebuild Qt and your application. This should ensure that wchar_t is treated as built-in type.
How can I create a QSettings group that is sorted numerically?
QSettings http://doc.qt.io/qt-5/qsettings.html uses a QMap http://doc.qt.io/qt-5/qmap.html underneath to store the items, and a QMap is always sorted alphabetically. There is nothing you can do to change that to a numerical sorting. What you can do however is to handle this yourself by registering your own format, then you can pass in your own functions that will read and write QSettings key/value pairs the way you want, see:
http://doc.qt.io/qt-5/qsettings.html#registerFormat
How can I display a tooltip over only one word in a QLabel?
It is hard to achieve this with a QLabel http://doc.qt.io/qt-5/qlabel.html since there is no direct API for determining when the mouse is over the individual words in the QLabel. What you can do instead however, is to create a QTextEdit http://doc.qt.io/qt-5/qtextedit.html that looks like a QLabel. Then you can reimplement event() http://doc.qt.io/qt-5/qabstractscrollarea.html#event and listen for the QEvent::ToolTip http://doc.qt.io/qt-5/qevent.html#Type-enum event and use QTextEdit::cursorForPosition() http://doc.qt.io/qt-5/qtextedit.html#cursorForPosition and QTextCursor::select(QTextCursor::WordUnderCursor) to check the word that's under the cursor.
See the documentation:
http://doc.qt.io/qt-5/qtextcursor.html#select http://doc.qt.io/qt-5/qtextcursor.html#SelectionType-enum
The following example illustrates how this can be done.
#include <QtWidgets>
class TextEdit : public QTextEdit
{
Q_OBJECT
public:
TextEdit(QWidget *parent) : QTextEdit(parent)
{
setTextInteractionFlags(Qt::TextBrowserInteraction);
setFrameStyle(QFrame::NoFrame);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setText(This application only provides a tooltip for the following word: polymorphism);
QPalette pal = palette();
pal.setColor(QPalette::Base, QColor(1, 0.941176, 0.941176, 0.941176) );
setReadOnly(true);
setPalette(pal);
setFixedHeight(18);
setFixedWidth(400);
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
}
bool event(QEvent* event) {
if (event->type() == QEvent::ToolTip)
{
QHelpEvent* helpEvent = static_cast <QHelpEvent*>(event);
QTextCursor cursor = cursorForPosition(helpEvent->pos());
cursor.select(QTextCursor::WordUnderCursor);
if (cursor.selectedText() == polymorphism)
QToolTip::showText(helpEvent->globalPos(), cursor.selectedText());
else
QToolTip::hideText();
return true;
}
return QTextEdit::event(event);
}
void scrollContentsBy ( int dx, int dy )
{
}
};
#include main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QWidget wid;
TextEdit *edit = new TextEdit(&wid);
TextEdit *edit2 = new TextEdit(&wid);
QVBoxLayout *layout = new QVBoxLayout(&wid);
layout->addWidget(edit);
layout->addWidget(edit2);
wid.show();
return app.exec();
}
How can I convert a colored QPixmap into a grayscaled QPixmap?
One way to convert a colored QPixmap http://doc.qt.io/qt-5/qpixmap.html into a grayscaled QPixmap, and probably the easiest, is to convert it into a QImage http://doc.qt.io/qt-5/qimage.html first. Then you can iterate over the image pixels and use QColor::qGray() http://doc.qt.io/qt-5/qcolor.html#qGray to convert the rgb into grayscale. After that you convert it back to a QPixmap.
The following example illustrates how this can be done:
#include <QtWidgets>
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QPixmap pixmap("logo.png");
QImage image = pixmap.toImage();
QRgb col;
int gray;
int width = pixmap.width();
int height = pixmap.height();
for (int i = 0; i < width; ++i)
{
for (int j = 0; j < height; ++j)
{
col = image.pixel(i, j);
gray = qGray(col);
image.setPixel(i, j, qRgb(gray, gray, gray));
}
}
pixmap = pixmap.fromImage(image);
QLabel label;
label.setPixmap(pixmap);
label.show();
return app.exec();
}
Why do I get the following error: QtMain.lib(qtmain_win.obj) : fatal error LNK1103: debugging information corrupt; recompile module?
This error can occur when downloading the wrong binary package, e.g when downloading qt-win-commercial-4.6.3-vs2008.exe and using it with Visual Studio 2005, so make sure you have downloaded the correct package.
This error can also occur when having 2 compilers installed and not using the same compiler that was used for building the package. In this case, you need to ensure that your environment is set up correctly for the compiler you want to use. If you have installed the binary package for VS 2008 for example, you need to use it with the VS 2008 compiler. In order to do so, then use the command prompt provided with the binary package or select the Visual Studio with Qt SomeVersion option in the Start menu.
You can check if the correct compiler is set up in your environment, by typing
set
in the command prompt provided with the binary package. Then you need to make sure the compiler you want to use is listed first in your PATH environment variable.
Alternatively, you can use the command prompts provided with Visual Studio and call
set qmakespec=theMkSpecYouUse
PATH=%path%;yourQtVersion/bin;
to make sure you use the Qt version built with that compiler.
"When creating a custom library on Winows and trying to use it in my application, then why do I get the error cannot open file ��yLibrary.lib?"
In order for the myLibrary.lib file to be created, you need to ensure that the symbols in your library are properly exported when the library is created and subsequently imported when you are linking against the library. The following wiki page http://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application contains detailed information on how this can be done
Why do I get the error 'libpq-fe.h': No such file or directory when trying to build the psql plugin?
The reason you get this error is because qmake can't locate the header files for the Postgres client. You need to ensure that the Postgres client include files are added to the environment, for example by adding them to the INCLUDE environment variable or to the INCLUDEPATH in the .profile. Note that if the header files exist in a directory with spaces in it, you need to quote the path since qmake does not support paths with spaces in them, e.g:
INCLUDEPATH+=$$quote(c:\program files......)
Similarly, you need to add the library files to the LIB environment variable or the LIBS variable in the .pro file.
How can I use several Qt based dlls in an external application?
In order to use several dlls created with Qt in an external application, you need to do the following:
- ensure that only one QCoreApplication/QApplication instance exists, by checking if qApp http://doc.qt.io/qt-5/qapplication.html#qApp exists before creating the application instance.
- export the dlls using __declspec(dllexport)
- if your Qt based dlls depend on different versions of Qt, you need to ensure that the right ones are picked up for each dll by configuring Qt with the qtlibinfix and namespace options http://doc.qt.io/qt-5/configure-options.html to ensure that each dll has a unique name and to avoid symbol conflicts:
configure -qtlibinfix customName -qtnamespace theNamespace
How can I create a 3rd party plugin using Qt that performs event handling?
When creating a 3rd party Qt plugin/library that performs event handling, then you need to have an eventloop running that takes care of the event handling for you. This can be done in three ways:
1) You can instantiate a QCoreApplication/QApplication instance and call exec() http://doc.qt.io/qt-5/qcoreapplication.html#exec on it to start the event handling and call quit() http://doc.qt.io/qt-5/qcoreapplication.html#quit when the plugin unloads. Using this approach, the rest of the application will be blocked as long as the event loop is running.
2) You can call processEvents() http://doc.qt.io/qt-5/qcoreapplication.html#processEvents on the application periodically and with the help of timers control the event handling yourself. Using this approach, the plugin will still block, but only until there are no more events to process, which allows you to go back to the main application. In addition you have control over when these events should be processed.
3) Your Non-Gui Qt objects can reside in a worker thread that has an event loop in it to avoid having to call exec()/processevents() on the application. The event loop can be started by calling QThread::exec() http://doc.qt.io/qt-5/qthread.html#exec.
Note that you need to create a QApplication (or QCoreApplication) object before you can create a QThread, but you don't need to call exec() on it though. You can find more information on threads and event loops here http://doc.qt.io/qt-5/threads-qobject.html#per-thread-event-loop.
Even though the GUI classes only can be used from the main thread, the worker thread can request updates on GUI objects by either posting an event or by emitting signals. See:
http://doc.qt.io/qt-5/threads-qobject.html#signals-and-slots-across-threads
What is the difference between the QPSQL7 and QPSQL drivers?
There is not really a difference between the QPSQL7 and QPSQL drivers. QPSQL7 is there for compatibility with Qt 3, so it is best to use QPSQL. It would make no actual difference if you used QPSQL7 though.
Why do I get linking errors issued from moc when building my project?
Errors like the following:
Error 1 error LNK2001: unresolved external symbol public: virtual struct QMetaObject const * __thiscall myApp_qt::metaObject(void)const (?metaObject@myApp@@UBEPBUQMetaObject@@XZ) myApp.obj myApp)
are typically issued by the moc http://doc.qt.io/qt-5/moc.html#moc preprocessor and indicate that there is no moc-generated cpp file, or the moc-generated cpp-file is not compiled and linked into your project.
You can try regenerating the .vcproj file on the command line to see if this helps. This can have an effect in situations where the .vcproj file has not been updated with information about the moc file. Open the command prompt provided with Qt in the Start menu and you go to your project's directory and type
qmake -tp vc
devenv yourProject.vcproj
to see if that helps.
The attached projects demonstrate the 2 possible ways of linking the moc generated code with your application. In the single main.cpp, the class declaration is in the .cpp file and we need to include the moc generated file into the application by adding the following line:
#include "nameOfFile.moc"
In the .zip file, the class declaration is in the .h file and the moc output will then be put in a file called moc_myclass.cpp. This file should be compiled and linked as normal.
Can I use _CrtMemCheckpoint, _CrtMemDifference and friends to look for memory leaks in my Qt application?
We don't actually advise using _CrtMemCheckpoin and _CrtMemDifference since this approach is not a reliable way to check for memory leaks with Qt. The reason for this is that the memory detection is done before the Qt dlls are unloaded. Therefore it will see things that have yet to be cleaned up by Qt when the Qt dll is unloaded.
Instead we recommend using Purify or Boundschecker on Windows.
What is needed for deploying a Phonon based application?
In order to distribute your Phonon based application to another machine, you need to deploy the following along with your application:
Application directory:
- yourApplication.exe
- Visual Studio Redistributable Package
- phonon4.dll
- QtCore4.dll
- QtGui4.dll
- QtOpenGL4.dll
- phonon_backend (directory)
It is necessary to copy the QtOpenGL4.dll since the phonon backend relies on this on Windows. The folder named phonon_backend above needs to contain the following file:
phonon_ds9d4.dll
If you are using MinGW, then you need to deploy
libgcc_s_dw2-1.dll 11.362 mingwm10.dll
instead of the Visual Studio Redistributable Package.
When clicking a custom item delegate, how can I ensure that its row gets selected in the QTableView?
You need to ensure that whenever a mouse event occurs on a widget that you programatically select the row underneath it as the QTableView http://doc.qt.io/qt-5/qtableview.html itself will not be getting the mouse event. The problem with this is that you need to have some way of tying in the widget to a row so that you know which row to call select() for. In the attached example a map is used to connect a widget to a row. The delegate's eventFilter() http://doc.qt.io/qt-5/qstyleditemdelegate.html#eventFilter is reimplemented and installed on the widgets, so that whenever a mouse press occurs, the event filter emits a signal causing the row to be selected.
In addition QStyledItemDelegate::paint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#paint is reimplemented. This is necessary because when clicking on a widget, it takes focus and the table will then not be the active widget and hence show an inactive selection.
#include
<QtGui>
class MyStyledItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
MyStyledItemDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {}
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QWidget *w = new QWidget(parent);
QLineEdit *le = new QLineEdit(w);
le->installEventFilter((QObject *)this);
MyStyledItemDelegate *that = (MyStyledItemDelegate *)this;
that->rowMap.insert(w, index.row());
return w;
}
bool eventFilter(QObject *object, QEvent *event)
{
bool ret = QStyledItemDelegate::eventFilter(object, event);
if (event->type() == QEvent::MouseButtonPress) {
QWidget *w = (QWidget *)object;
int row = rowMap.value(w, -1);
while (row == -1 && w) {
w = w->parentWidget();
row = rowMap.value(w, -1);
}
if (row != -1)
emit selectRow(row);
}
return ret;
}
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if( index.row() ==2 &&option.state & QStyle::State_Selected ) {
QStyledItemDelegate::paint(painter, option, index);
painter->fillRect(option.rect, option.palette.highlight());
painter->drawText(option.rect, Qt::AlignLeft | Qt::AlignVCenter, index.data().toString());
} else {
return QStyledItemDelegate::paint(painter, option, index);
}
}
signals:
void selectRow(int);
private:
QMap<QWidget *, int> rowMap;
};
#include main.moc"
int main(int argc, char **argv)
{
QApplication a(argc, argv);
QTableView tv;
tv.setSelectionBehavior(QTableView::SelectRows);
tv.setModel(new QStandardItemModel(5, 5, &tv));
MyStyledItemDelegate *msid = new MyStyledItemDelegate(&tv);
tv.setItemDelegate(msid);
tv.openPersistentEditor(tv.model()->index(2,2));
QObject::connect(msid, SIGNAL(selectRow(int)), &tv, SLOT(selectRow(int)));
tv.show();
return a.exec();
}
Is it possible to embed one Qt process into another Qt process?
There is no Qt API for embedding a Qt application into another Qt application. If you wish to use widgets from one Qt application in another, then you can use Qt's QAxServer http://doc.qt.io/qt-5/qaxserver.html module to turn your application executable into an out-of-process ActiveX server that can run the control.
The client application can then use Qt's QAxContainer http://doc.qt.io/qt-5/qaxcontainer.html to embed the control. Note however that widgets can't co-exist in 2 different applications. The QAxServer will create a new instance of the widget whenever it is queried, as widgets can't be shared between applications.
How to emulate keystroke F1 for use in Qt/MFC Migration Framework solution?
The code sample below shows how to emit a F1 key stroke from the QPushButton::clicked() http://doc.qt.io/qt-5/qabstractbutton.html#clicked signal (in your Qt application) when wanting your MFC parent application to receive it (not your Qt application). The example uses the Windows API to achieve this:
#ifdef WIN32
#include <windows.h>
#endif
void CMyQtDlg::on_btn_help_clicked()
{
#ifdef WIN32
if (parentWidget())
{
PostMessage(parentWidget()->winId(), WM_KEYDOWN, VK_F1, 0);
PostMessage(parentWidget()->winId(), WM_KEYUP, VK_F1, 0);
}
#endif
}
Is there a way to create thumbnail for video files?
One way to create a thumbnail for video files is to use QPixmap::grabWindow() http://doc.qt.io/qt-5/qpixmap.html#grabWindow to construct a pixmap by grabbing the contents of the given window and then QPixmap::save() http://doc.qt.io/qt-5/qpixmap.html#save to save it.
The problem with this approach is that if there is any overlapping content it will also grab the overlapping content.
Another approach, is to use Phonon to load the movie and then use QPixmap::grabWidget() http://doc.qt.io/qt-5/qpixmap.html#grabWidget on the video widget to grab a screenshot of it that you can use as the thumbnail.
Why do my widgets have a light background in Designer when using QCleanlooksStyle, but a dark background when running the app?
By default we use the system palette for the background. In Designer http://doc.qt.io/qt-5/designer-manual.html however, the palette is explicitly set. If you want the same palette as in Designer, you can set it as follows:
app.setPalette(app.style()->standardPalette());
See the documentation on standardPalette() http://doc.qt.io/qt-5/qcleanlooksstyle.html#standardPalette
See the following example:
int main(int argc, char** argv)
{
QApplication app(argc, argv);
app.setStyle(new QCleanlooksStyle());
app.setPalette(app.style()->standardPalette());
QWidget window;
window.show();
return app.exec();
}
Using QGraphicsLineItem with zoom-level-independent selectable regions
If you have a QGraphicsLineItem http://doc.qt.io/qt-5/qgraphicslineitem.html in a QGraphicsScene http://doc.qt.io/qt-5/qgraphicsscene.html with a thin pen, then it can get quite hard to select and/or move it, especially when you zoom out. It is possible to define an invisible region around the line, in which one can select/pick the line, and which is independent of the zoom-level. To do this, one has to reimplement the shape function of the QGraphicLineItem and scale its pen width to the zoomlevel, like this:
QPainterPath MyLine::shape() const
{
QPainterPath path;
if (line() == QLineF())
return path;
path.moveTo(line().p1());
path.lineTo(line().p2());
QPen pen1 = pen();
MyGraphicsScene * scene1 = qobject_cast<MyGraphicsScene*>(scene());
if (scene1)
pen1.setWidth(pickWidth/scene1->scalefactor);
return qt_graphicsItem_shapeFromPath(path, pen1);
}
Note, for this to work, one has to copy the function
static QPainterPath qt_graphicsItem_shapeFromPath(const QPainterPath &path, const QPen &pen)
from the file qgraphicsitem.cpp
In the attached example, you can find this idea implemented.
What can cause the data passed in to QNetworkAccessManager::post() not to be posted when using a sequential QIODevice subclass?
This problem can be caused by the readData() http://doc.qt.io/qt-5/qiodevice.html#readData reimplementation never returning -1 and hence not informing that there is no more data to be read. If readData() never returns -1, the data will never be sent because it keeps waiting to be told that there is no more data to be sent. The following report in Jira http://bugreports.qt.io/browse/QTBUG-7648 contains more information on this.
How can I speed up the performance when using QTableWidget::selectRow()?
It is a known issue that QTableWidget::selectRow() http://doc.qt.io/qt-5/qtableview.html#selectRow is slow for large datasets, especially when the items you want to select are spread out over the table.
In order to speed things up, you can use a model with a QTableView http://doc.qt.io/qt-5/qtableview.html instead and subclass QStyledItemDelegate http://doc.qt.io/qt-5/qstyleditemdelegate.html and reimplement its paint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#paint method. In there you can change the option passed in so that the State_Selected http://doc.qt.io/qt-5/qstyle.html#StateFlag-enum is included in the state variable if the index should be painted as selected. Then you can call the base class implementation with the modified option. That way you don't have to do much beyond checking your own storage to see if something should be selected or not.
In order to handle manual mouse selections, you can catch these by handling it yourself in the mousePressEvent() http://doc.qt.io/qt-5/qabstractitemview.html#mousePressEvent, there you can check the modifiers() http://doc.qt.io/qt-5/qinputevent.html#modifiers for the event passed in to see if Ctrl or Shift is being held.
To determine which item is actually being clicked on you can use indexAt() http://doc.qt.io/qt-5/qabstractitemview.html#indexAt so that you get the index of the item being selected/deselected.
The example below demonstrates how you can implement the itemdelegate part of this.
#include <QtWidgets>
class ItemDelegate : public QStyledItemDelegate
{
public:
ItemDelegate(QTableView *view)
{
myView = view;
QModelIndex start = myView->model()->index(0,0);
mySelectionList = myView->model()->match (start, Qt::DisplayRole, start, -1, Qt::MatchExactly);
}
void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
if (mySelectionList.contains(index)) {
QStyleOptionViewItem newOption =option;
newOption.state = newOption.state | QStyle::State_Selected;
return QStyledItemDelegate::paint(painter, newOption, index);
} else {
QStyledItemDelegate::paint(painter, option, index);
}}
private:
QTableView *myView;
QModelIndexList mySelectionList;
};
class TableView : public QTableView
{
Q_OBJECT
public:
TableView()
{
setSelectionMode(QAbstractItemView::MultiSelection);
myModel = new QStringListModel(this);
for (int i = 0; i < 500; i++) {
myList.append(start);
}
for (int i = 500; i < 1000; i++) {
myList.append(middle);
}
for (int i = 1000; i < 2100; i++) {
myList.append(start);
}
myModel->setStringList(myList);
setModel(myModel);
ItemDelegate *myDelegate = new ItemDelegate(this);
setItemDelegate(myDelegate);
}
private:
QStringListModel *myModel;
QStringList myList;
};
#include main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
TableView window;
window.show();
return app.exec();
}
How can I detect whether a checkbox was clicked in my QTreeView?
In order to detect whether the checkbox and not the text of an item was clicked in a QTreeView http://doc.qt.io/qt-5/qtreeview.html, then you can reimplement the mousePressEvent() http://doc.qt.io/qt-5/qtreeview.html#mousePressEvent and calculate the position of the checkbox there. If the mouse is over the calculated position, then you can for example emit a signal to notify it and do your own handling. Otherwise, simply call the base implementation.
The example below demonstrates how this can be done.
#include <QtWidgets>
class TreeWidget : public QTreeWidget
{
public:
TreeWidget()
{
setColumnCount(1);
item1 = new QTreeWidgetItem(this);
item1->setExpanded(true);
item1->setFlags(item1->flags() | Qt::ItemIsUserCheckable);
item1->setCheckState(0, Qt::Checked);
item1->setText(0, item 1);
item2 = new QTreeWidgetItem(item1);
item2->setFlags(item2->flags() | Qt::ItemIsUserCheckable);
item2->setCheckState(0, Qt::Checked);
item2->setText(0, item 2);
item3 = new QTreeWidgetItem(this);
item3->setText(0, item 3);
item3->setFlags(item3->flags() | Qt::ItemIsUserCheckable);
item3->setCheckState(0, Qt::Checked);
}
void mousePressEvent(QMouseEvent *event)
{
QModelIndex indexClicked = indexAt(event->pos());
if(indexClicked.isValid()) {
QRect vrect = visualRect(indexClicked);
int itemIndentation = vrect.x() - visualRect(rootIndex()).x();
QRect rect = QRect(header()->sectionViewportPosition(0) + itemIndentation
, vrect.y(), style()->pixelMetric(QStyle::PM_IndicatorWidth), vrect.height());
if(rect.contains(event->pos())) {
qDebug() << checkbox clicked;
QTreeWidget::mousePressEvent(event);
return;
} else {
QTreeWidget::mousePressEvent(event);
}}}
private:
QTreeWidgetItem *item1;
QTreeWidgetItem *item2;
QTreeWidgetItem *item3;
QTreeWidgetItem *item4;
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
TreeWidget box;
box.show();
return app.exec();
}
How can I replace the checkbox indicator of a QListWidgetItem with an icon?
In order to style the checkbox indicator of a QListWidgetItem http://doc.qt.io/qt-5/qlistwidgetitem.html, you can set a stylesheet on the QListWidget http://doc.qt.io/qt-5/qlistwidget.html that passes in the image you want when the subcontrol is :item http://doc.qt.io/qt-5/stylesheet-reference.html#list-of-sub-controls and the pseudo states http://doc.qt.io/qt-5/stylesheet-reference.html#list-of-pseudo-states are :checked, :unchecked and :indeterminate, see the documentation:
The example below demonstrates how this can be done.
#include <QtWidgets>
class ListWidget : public QListWidget
{
public:
ListWidget()
{
QListWidgetItem *firstItem = new QListWidgetItem(First, this);
firstItem->setFlags(firstItem->flags() |Qt::ItemIsUserCheckable);
firstItem->setCheckState(Qt::Checked);
QListWidgetItem *secondItem = new QListWidgetItem(Second, this);
addItem(firstItem);
addItem(secondItem);
setStyleSheet(QListWidget::indicator:checked { image: url(checked.png);} \
QListWidget::indicator:unchecked { image: url(unchecked.png)}\
QListWidget::indicator:indeterminate { image: url(indeterminate.png);}"
);
}};
int main(int argc, char** argv)
{
QApplication app(argc, argv);
ListWidget window;
window.show();
return app.exec();
}
How can I make long text appear elided for a QAction?
In order to make long text appear elided, you can use QFontMetrics::elidedText() http://doc.qt.io/qt-5/qfontmetrics.html#elidedText and pass in the width for which you want the text to appear elided.
The example below demonstrates how this can be done.
#include <QtWidgets>
class MainWindow : public QMainWindow
{
public:
MainWindow()
{
QMenu *menu = menuBar()->addMenu(Test);
QAction *firstAction = new QAction(this);
QString firstText = fontMetrics().elidedText(Normal Text, Qt::ElideMiddle, 100);
firstAction->setText(firstText);
menu->addAction(firstAction);
QAction *secondAction = new QAction(this);
QString secondText = fontMetrics().elidedText(Some wiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiide text, Qt::ElideMiddle,100);
secondAction->setText(secondText);
menu->addAction(secondAction);
setCentralWidget(new QTextEdit(this));
}
};
int main(int argc, char** argv)
{
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
How can I remove the dotted rectangle from the cell that has focus in my QTableView?
In order to remove the dotted rectangle that appears when a cell is clicked, then you can subclass the QStyledItemDelegate http://doc.qt.io/qt-5/qstyleditemdelegate.html class and reimplement the paint() http://doc.qt.io/qt-5/qstyleditemdelegate.html#paint function to remove the State_HasFocus http://doc.qt.io/qt-5/qstyle.html#StateFlag-enum state from the option's state, so that the dotted focus rectangle does not appear.
The example below demonstrates how this can be done.
#include <QtWidgets>
class StyledItemDelegate : public QStyledItemDelegate
{
public:
StyledItemDelegate(QObject *parent = NULL) :
QStyledItemDelegate(parent) {}
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QStyleOptionViewItem opt = option;
opt.state &= ~QStyle::State_HasFocus;
QStyledItemDelegate::paint(painter, opt, index);
}
};
static int ROWS = 5;
static int COLS = 5;
class TableWidget : public QTableWidget
{
Q_OBJECT
public:
TableWidget(QWidget *parent = nullptr)
: QTableWidget(ROWS, COLS, parent)
{
setItemDelegate(new StyledItemDelegate(this));
setSelectionMode(QAbstractItemView::SingleSelection);
setSelectionBehavior(QAbstractItemView::SelectRows);
for (int i=0; i<rowCount(); ++i) {
for (int j=0; j<columnCount(); ++j) {
setItem(i, j, new QTableWidgetItem(QString(%1).arg(i *
rowCount() + j)));
}
}
}
};
#include main.moc"
int main(int argc, char **argv)
{
QApplication a(argc, argv);
TableWidget w;
w.show();
return a.exec();
}
Is it possible to translate the native filedialogs used on Windows and Mac ?
This is not possible, since they are provided by Windows. The filedialogs will get the text of the language of the Windows/Mac version. So if you are on a German version of Windows, the buttons etc. in the native filedialog will appear in German. There is nothing we can do to change that in Qt.
How can I set up my environment for building Qt/Qt applications with MinGW?
In order to build Qt with MinGW, then follow these steps:
1) Download MinGW from our ftp site. There is a link to it in the compiler notes here http://doc.qt.io/qt-5/4.7/platform-notes-windows.html
The patched version is a version with more support for DirectShow. That is required if you want to build the phonon DirectShow backend, if you don't need to build that we require mingw-gcc 4.4 or up as a compiler.
2) Download the qt-everywhere-someVersion.zip package
3) Open a command prompt by typing
cmd
in Run/Search in the Start Menu
4) Set up the environment as follows in this command prompt:
set PATH=yourPathToMinGW\bin;%PATH% set INCLUDE= set LIB= set QMAKESPEC=win32-g++
and then type
configure -anyOptionsYouWant && mingw32-make
in this command prompt
5) When building Qt applications, add yourQtVersion\bin to the PATH environment variable like:
set PATH=yourQtVersion\bin;%PATH%
QWidget ::activateWindow() - behavior under windows
The documentation for QWidget::activateWindow() http://doc.qt.io/qt-5/qwidget.html#activateWindow states:
On Windows, if you are calling this when the application is not currently the active one then it will not make it the active window. It will change the color of the taskbar entry to indicate that the window has changed in some way. This is because Microsoft does not allow an application to interrupt what the user is currently doing in another application."
However, there is a workaround for this problem. Namely changing the following registry keys will result in the desired behaviour
HKEY_CURRENT_USER\Control Panel\Desktop
ForegroundFlashCount = REG_DWORD 0x00000003
ForegroundLockTimeout = REG_DWORD 0x00000000
These registry entries can be set using QSettings http://doc.qt.io/qt-5/qsettings.html .
e.g:
QSettings settings("HKEY_CURRENT_USER\\Control Panel\\Desktop ", QSettings::NativeFormat, this);
settings.setValue("ForegroundFlashCount", 3);
settings.setValue("ForegroundLockTimeout", 0 );
Note that changing these registry settings using QSettings will change them globally on your computer, not only for your application.
A restart of the computer, or a user log-off and relog-on is required after changing the registry keys to make this work.
It has been suggested to add this workaround to the Qt Documentation, see: http://bugreports.qt.io/browse/QTBUG-14062
How can I show close(x) button for each tab in a QMdiArea?
In order to show close buttons on the tabbed windows in a QMdiArea http://doc.qt.io/qt-5/qmdiarea.html, you need to get hold of the underlying QTabBar http://doc.qt.io/qt-5/qtabbar.html and call setTabsClosable() http://doc.qt.io/qt-5/qtabbar.html#tabsClosable-prop with true as an argument on it. Then you can connect its tabCloseRequested() http://doc.qt.io/qt-5/qtabbar.html#tabCloseRequested signal to a slot that closes the relevant tab.
The example below illustrates how this can be done.
#include <QtWidgets>
class MdiArea : public QMdiArea
{
Q_OBJECT
public:
MdiArea(QWidget *parent) : QMdiArea(parent)
{
setViewMode(QMdiArea::TabbedView);
QMdiSubWindow *subWindow1 = new QMdiSubWindow;
subWindow1->setWidget(new QTextEdit(this));
subWindow1->setAttribute(Qt::WA_DeleteOnClose);
addSubWindow(subWindow1);
QMdiSubWindow *subWindow2 = addSubWindow(new QPushButton(some text), 0);
QList<QTabBar*> tabBarList = findChildren <QTabBar*>();
tabBar = tabBarList.at(0);
if (tabBar) {
tabBar->setTabsClosable(true);
connect(tabBar, SIGNAL(tabCloseRequested(int)), this, SLOT(testSlot(int)));
}}
public slots:
void testSlot(int closeThisTab)
{
tabBar->removeTab(closeThisTab);
}
private:
QTabBar *tabBar;
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow()
{
area = new MdiArea(this);
setCentralWidget(area);
QToolBar *toolBar = new QToolBar(this);
QAction *closeAction = new QAction(this);
closeAction->setText(Close all);
toolBar->addAction(closeAction);
addToolBar(toolBar);
connect(closeAction, SIGNAL(triggered(bool)), this, SLOT(testSlot(bool)));
}
public slots:
void testSlot(bool closeThem)
{
area->closeAllSubWindows();
}
private:
MdiArea *area;
};
#include main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
How can I drag items between a QToolBar and a QListWidget?
In order to allow toolbuttons to be dragged from a QToolBar http://doc.qt.io/qt-5/qtoolbar.html and dropped as items in a QListWidget http://doc.qt.io/qt-5/qlistwidget.html, then you need to make the widgets aware of drag and drop operations. This can be done by subclassing QToolButton http://doc.qt.io/qt-5/qtoolbutton.html and implementing a function for it that stores the data that is to be transferred in a QMimeData http://doc.qt.io/qt-5/qmimedata.html object.
Then in order for the QListWidget to receive the data, you need to reimplement its dragEnterEvent() http://doc.qt.io/qt-5/qabstractitemview.html#dragEnterEvent, dragMoveEvent() http://doc.qt.io/qt-5/qlistview.html#dragMoveEvent and dropEvent () http://doc.qt.io/qt-5/qlistwidget.html#dropEvent functions, in addition to calling setAcceptDrops() http://doc.qt.io/qt-5/qwidget.html#acceptDrops-prop with true as an argument.
Similarly, in order to drag items from the QListWidget to the QToolBar, you can reimplement QListWidget::startDrag() http://doc.qt.io/qt-5/qlistview.html#startDrag and store the data in a QMimeData object that the toolbar will receive.
The example below illustrates how this can be done.
#include <QtWidgets>
class ToolButton : public QToolButton
{
Q_OBJECT
public:
ToolButton(QWidget *parent) : QToolButton(parent)
{
connect(this, SIGNAL(pressed()), this, SLOT(startDrag()));
}
public slots:
void startDrag()
{
QDrag *dr = new QDrag(this);
// The data to be transferred by the drag and drop operation is contained in a QMimeData object
QMimeData *mimeData = new QMimeData;
QByteArray ba = text().toLatin1().data();
QString theText = bla/x-something;
mimeData->setData(theText, ba);
// Assign ownership of the QMimeData object to the QDrag object.
dr->setMimeData(mimeData);
// Start the drag and drop operation
if (dr->start(Qt::MoveAction))
deleteLater();
}
};
class ToolBar : public QToolBar
{
public:
ToolBar(QMainWindow *window) : QToolBar(window)
{
setAcceptDrops(true);
}
void dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasFormat(bla/x-something))
event->acceptProposedAction();
}
void dropEvent(QDropEvent *event)
{
if (event->mimeData()->hasFormat(bla/x-something)) {
event->accept();
event->setDropAction(Qt::MoveAction);
QByteArray pieceData = event->mimeData()->data(bla/x-something);
QDataStream dataStream(&pieceData, QIODevice::ReadOnly);
ToolButton *button = new ToolButton(this);
button->setText(pieceData);
addWidget(button);
} else {
event->ignore();
}
}
};
class ListWidget : public QListWidget
{
Q_OBJECT
public:
ListWidget(QWidget *parent) : QListWidget(parent)
{
addItem(First);
addItem(Second);
addItem(Third);
setDragEnabled(true);
setAcceptDrops(true);
}
void dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasFormat(bla/x-something))
event->accept();
else
event->ignore();
}
void dragMoveEvent(QDragMoveEvent *event)
{
if (event->mimeData()->hasFormat(bla/x-something)) {
event->setDropAction(Qt::MoveAction);
event->accept();
} else
event->ignore();
}
Qt::DropActions supportedDropActions () const
{
return Qt::MoveAction;
}
void dropEvent(QDropEvent *event)
{
if (event->mimeData()->hasFormat(bla/x-something)) {
event->accept();
event->setDropAction(Qt::MoveAction);
QByteArray pieceData = event->mimeData()->data(bla/x-something);
addItem(pieceData);
} else
event->ignore();
}
void startDrag(Qt::DropActions)
{
QListWidgetItem *item = currentItem();
QMimeData *mimeData = new QMimeData;
QByteArray ba = item->text().toLatin1().data();
QString theText = bla/x-something;
mimeData->setData(theText, ba);
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
if (drag->exec(Qt::MoveAction) == Qt::MoveAction)
delete takeItem(row(item));
}
};
#include main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QMainWindow window;
window.setCentralWidget(new ListWidget(&window));
ToolBar *toolBar = new ToolBar(&window);
ToolButton *button1 = new ToolButton(toolBar);
button1->setText(Button 1);
ToolButton *button2 = new ToolButton(toolBar);
button2->setText(Button 2);
toolBar->addWidget(button1);
toolBar->addWidget(button2);
window.addToolBar(toolBar);
window.show();
return app.exec();
}
When setting a background pixmap for a widget, it is tiled if the pixmap is smaller than the widget. Is there a way to avoid this?
In order to avoid the image from being tiled, you can catch the resizeEvent() http://doc.qt.io/qt-5/qwidget.html#resizeEvent and scale it to fit the size of the widget. The example below illustrates how this can be done. It creates a new image the same size as the widget, fills it with gray, and then draws the background image centered on it, with the aspect ratio preserved.
#include <QtWidgets>
class MdiArea : public QMdiArea
{
Q_OBJECT
public:
MdiArea()
{
i = QImage(logo.png);
}
protected:
void resizeEvent(QResizeEvent *resizeEvent)
{
QImage newBackground(resizeEvent->size(), QImage::Format_ARGB32_Premultiplied);
QPainter p(&newBackground);
p.fillRect(newBackground.rect(), Qt::gray);
QImage scaled = i.scaled(resizeEvent->size(),Qt::KeepAspectRatio);
QRect scaledRect = scaled.rect();
scaledRect.moveCenter(newBackground.rect().center());
p.drawImage(scaledRect, scaled);
setBackground(newBackground);
QMdiArea::resizeEvent(resizeEvent);
}
private:
QImage i;
};
#include main.moc"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
MdiArea box;
box.resize(400, 400);
box.show();
return app.exec();
}
The performance is slow and some data is lost when sending data using QTcpSocket at short intervals, what can be wrong?
The performance of QTcpSocket http://doc.qt.io/qt-5/qtcpsocket.html can decrease and data can get lost if the socket is not set up correctly in the application. If the socket and server are handled in the same class and the QTcpSocket object is being reused, then this can cause the problem. The recommended pattern is:
- Don't do client and server in same class.
- If you for some reason have to do it in the same class, then don't handle multiple sockets with one object. Make sure the QTcpSocket object is created locally in each function and ensure that it is deleted when it is disconnected, e.g:
void processReadyRead()
{
QTcpSocket* mySocket = qobject_cast<QTcpSocket*>(sender());
...
connect(mySocket, SIGNAL(disconnected()), mySocket, SLOT(deleteLater()));
}
The example below demonstrates how this can be set up.
#include <QtWidgets>
#include <QtNetwork>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow()
{
textEdit = new QTextEdit(this);
setCentralWidget(textEdit);
QTimer *timer = new QTimer(this);
timer->start(1);
myServer = new QTcpServer (this);
if (!myServer->listen(QHostAddress(127.0.0.1), 61031))
{
exit(-1); //error
}
connect(timer, SIGNAL(timeout()), this, SLOT(testSlot()));
connect(myServer, SIGNAL(newConnection()), this, SLOT(processNewConnection()));
}
public slots:
void processNewConnection()
{
//Create the socket locally using nextPendingConnection
QTcpSocket *testSocket = myServer->nextPendingConnection();
if (testSocket)
{
//Avoid memory leakage by deleting the socket when it is disconnected
connect(testSocket, SIGNAL(disconnected()), testSocket, SLOT(deleteLater()));
connect(testSocket, SIGNAL(readyRead()), this, SLOT(processReadyRead()));
connect(testSocket, SIGNAL(disconnected()), testSocket, SLOT(deleteLater()));
}
}
void processReadyRead()
{
//Use QOject::sender to get the socket that sent the data
QTcpSocket* mySocket = qobject_cast <QTcpSocket*>(sender());
QByteArray block = mySocket->readAll();
QDataStream in(&block, QIODevice::ReadOnly);
in.setVersion(QDataStream::Qt_4_0);
QString receiveString;
in >> receiveString;
textEdit->setText(receiveString);
connect(mySocket, SIGNAL(disconnected()), mySocket, SLOT(deleteLater()));
}
void testSlot()
{
QTcpSocket *aClientConnection = new QTcpSocket();
connect(aClientConnection, SIGNAL(disconnected()), aClientConnection, SLOT(deleteLater()));
aClientConnection->connectToHost(QHostAddress(127.0.0.1), 61031);
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
QString sendString;
for (int i=0;i<1000;i++)
sendString = Make sure the socket is created and destroyed locally in each function, don't reuse one object for them.;
out << sendString;
aClientConnection->write(block);
}
private:
QTcpServer *myServer;
QTextEdit *textEdit;
};
#include main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
How can I create a one-line QTextEdit?
You can create a single line QTextEdit http://doc.qt.io/qt-5/qtextedit.html by subclassing QTextEdit and doing the following:
1. Disable word wrap. 2. Disable the scroll bars (AlwaysOff). 3. setTabChangesFocus(true). 4. Set the sizePolicy to (QSizePolicy::Expanding, QSizePolicy::Fixed) 4. Reimplement keyPressEvent() to ignore the event when Enter/Return is hit 5. Reimplement sizeHint to return size depending on the font. It can be based on QLineEdit's sizeHint() http://doc.qt.io/qt-5/qlineedit.html#sizeHint.
The example below demonstrates how this can be done.
#include <QtWidgets>
class TextEdit : public QTextEdit
{
public:
TextEdit()
{
setTabChangesFocus(true);
setWordWrapMode(QTextOption::NoWrap);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
setFixedHeight(sizeHint().height());
}
void keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)
event->ignore();
else
QTextEdit::keyPressEvent(event);
}
QSize sizeHint() const
{
QFontMetrics fm(font());
int h = qMax(fm.height(), 14) + 4;
int w = fm.width(QLatin1Char('x')) * 17 + 4;
QStyleOptionFrameV2 opt;
opt.initFrom(this);
return (style()->sizeFromContents(QStyle::CT_LineEdit, &opt, QSize(w, h).
expandedTo(QApplication::globalStrut()), this));
}
};
int main(int argc, char** argv)
{
QApplication app(argc, argv);
TextEdit window;
window.show();
return app.exec();
}
How can I make Assistant look for translations outside qtVersion/translations when deploying my application?
You can provide a qt.conf http://doc.qt.io/qt-5/qt-conf.html file with your application which indicates where the translations are located.
The content of your qt.conf file can look something like the following for example:
[Paths]
Translations =c:\\xxx\\translations
How can I make the QSsl... classes work on Windows?
Make sure you have OpenSSL installed on your system and then follow the steps below to be able to use the QSsl... classes in your application.
1) Install OpenSSL from the following link:
Alternatively, from the link below which contains an installer that will ensure that OpenSSL installs correctly.
http://www.slproweb.com/products/Win32OpenSSL.html
2) Add global environment variables similar to the following:
INCLUDE=C:\OpenSSL-Win32\include;
LIB=C:\OpenSSL-Win32\lib;
PATH= C:\OpenSSL-Win32\bin
3) Configure Qt with the
configure -openssl
option
See also:
http://doc.qt.io/qt-5/ssl.html http://doc.qt.io/qt-5/requirements.html
"Why do I get the following error when using QPainter: QPainter::begin: Paint device returned engine == 0, type: 1?"
This error can occur if you try to use the painter on a subclass of QScrollArea http://doc.qt.io/qt-5/qscrollarea.html, and you don't pass in the viewport() http://doc.qt.io/qt-5/qabstractscrollarea.html#viewport as the device to paint on. So if you are painting on a QTableWidget http://doc.qt.io/qt-5/qtablewidget.html for instance, make sure you instantiate the painter as follows:
QPainter painter(tableWidget->viewport());
How can I display a flash file in a QWebView and ensure that nobody can copy the file?
In order to display flash videos, you need to set the PluginsEnabled http://doc.qt.io/qt-5/qwebsettings.html#WebAttribute-enum attribute on the object returned by QWebSettings.globalSettings() http://doc.qt.io/qt-5/qwebsettings.html#globalSettings. See the documentation http://doc.qt.io/qt-5/qtwebkit.html#netscape-plugin-support for more details about using plugins.
To make it impossible for others to copy the flash file, you can add it as a resource http://doc.qt.io/qt-5/resources.html, this way the file will be stored in the application executable.
Finally, you need to call
QWebSecurityOrigin::addLocalScheme(qrc)
to ensure the webview will understand the content from resource files, see the documentation on addLocalScheme() http://doc.qt.io/qt-5/qwebsecurityorigin.html#addLocalScheme
The example below illustrates this approach.
#include <QtWidgets>
#include <QtWebKit>
class WebView : public QWebView
{
public:
WebView()
{
settings()->globalSettings()->setAttribute(QWebSettings::PluginsEnabled, true);
QWebSecurityOrigin::addLocalScheme(qrc);
load(QUrl::fromLocalFile(AbsolutePathTo/A-Sample-SWF-File.htm));
}
};
#include main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
WebView window;
window.show();
return app.exec();
}
Why does not unicode characters show up for indices in my help documentation?
In order to make this work you need to save the .qhp file itself as unicode in a texteditor. The following steps should get this working:
1) Remove the encoding from the file 2) Keep the umlaut as it is literally in the file 3) Save the file as unicode 4) Clear the assistant cache under QDesktopServices::dataLocation/Trolltech
When using the Alt key as a shortcut in my application, then why don't I get a release event when hitting Alt+Tab?
Alt+Tab is a key combination controlled by Windows, so Windows will grab the event which is why you don't get a release event. If you need a key release event to be issued however, then you can listen for the QEvent::ActivationChange http://doc.qt.io/qt-5/qevent.html#Type-enum and if the Alt key is pressed when you get a QEvent::ActivationChange, then you can send the key release event yourself using QCoreApplication::sendEvent() http://doc.qt.io/qt-5/qcoreapplication.html#sendEvent
The example below illustrates how this can be done.
#include <QtWidgets>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow()
{
altIsPressed = false;
setFocusPolicy(Qt::StrongFocus);
}
bool event(QEvent *myEvent)
{
if (myEvent->type() == QEvent::ActivationChange && altIsPressed) {
qDebug() << Activation Change;
QKeyEvent *keyEvent = new QKeyEvent(QEvent::KeyRelease, Qt::Key_Alt, Qt::NoModifier);
QApplication::sendEvent(this, keyEvent);
}
return QMainWindow::event(myEvent);
}
void keyPressEvent(QKeyEvent *event)
{
if (event->modifiers() == Qt::AltModifier)
{
qDebug() << KEY PRESS;
altIsPressed = true;
return QMainWindow::keyPressEvent(event);
}
return QMainWindow::keyPressEvent(event);
}
void keyReleaseEvent(QKeyEvent *event)
{
qDebug() << KEY RELEASE;
altIsPressed = false;
return QMainWindow::keyReleaseEvent(event);
}
bool altIsPressed;
};
#include main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
After installing the binary Qt package for VS 2005, Qt Designer won't run, what is causing this problem?
designer.exe is part of the binary release of Qt for Windows. It was therefore built using Visual Studio 2005 with all available service packs and security patches applied. This broke binary compatibility with some versions of Visual Studio which don't have identically versioned C runtime dlls. An error message such as the following can occur when running into this issue:
- C:\Qt\4.7.1\bin\designer.exe: This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem.*
If you don't have all service packs and security patches applied for Visual Studio and don't wish to install them,then you can get around this problem by dowloading the Qt source package instead and building it as follows:
- Open the command prompt provided with Visual Studio 2005
- Go to the Qt directory and type
configure
nmake
- In this command prompt, type:
set PATH=%path%;yourPathToQt/bin;
set QMAKESPEC=win32-msvc2005
- Type: designer
QWidget is returned as the windows name on Windows, is there a way to change the windows name to make it unique?
There is no direct way to achieve this. However if you apply the following patch:
--- a/src/gui/kernel/qapplication_win.cpp
+++ b/src/gui/kernel/qapplication_win.cpp
const QString qt_reg_winclass(QWidget *w) // register window class
style = CS_DBLCLKS;
icon = true;
}
+ if (!w->objectName().isEmpty())
+ cname += QLatin1Char('_') + w->objectName();
#ifndef Q_OS_WINCE
// force CS_OWNDC when the GL graphics system is
then what you can do is call setObjectName() http://doc.qt.io/qt-5/qobject.html#objectName-prop on the widgets and it well then ensure that it is registered as:
QWidget_yourOwnNameHere
There is a suggestion for adding this functionality in Jira http://bugreports.qt.io/browse/QTBUG-11487.
Why do all Qt 4.7 applications crash when using Windows 7 x64 w/ VS 2010?
This problem is described in the following bug report:
http://bugreports.qt.io/browse/QTBUG-11445
The report above explains that this problem is not caused by a bug in Qt, but by a bug in the compiler and that the following hotfix should fix the problem:
http://support.microsoft.com/kb/2280741
Is there a way to know if a widget is currently using a stylesheet?
You can check if a widget has a stylesheet http://doc.qt.io/qt-5/stylesheet.html set by checking its QWidget::style() http://doc.qt.io/qt-5/qwidget.html#style value.
If it has a stylesheet set, then the value returned will be QStyleSheetStyle.
If you set a stylesheet on a parent widget however, then the child widgets will inherit the stylesheet, even though they don't have any properties that are specifically set for them in the stylesheet and the style returned for the children will be QStyleSheetStyle. So child widgets will implicitly have a stylesheet set when the parent has a stylesheet set. There is no Qt API for determening whether a child widget is mentioned in the parent widget's stylesheet, you would need to parse the stylesheet yourself to determine if that's the case.
How can I add comments to a .ini file when using QSettings?
QSettings http://doc.qt.io/qt-5/qsettings.html will overwrite the content of the INI file (and also writes the setting entries in alphabetical order), so any comments will be removed (and the ordering may not be what you expected it to be).
The only way to be able to add comments is to implement ReadFunc http://doc.qt.io/qt-5/qsettings.html#ReadFunc-typedefand WriteFunc http://doc.qt.io/qt-5/qsettings.html#WriteFunc-typedef to suit your requirements, and register these functions to use with the format of your choice with registerFormat() http://doc.qt.io/qt-5/qsettings.html#registerFormat.
How can I detect in the .pro file if I am compiling for a 32 bit or a 64 bit platform?
You can use QMAKE_TARGET.arch to decide the platform you are building for. You can do it as follows:
win32-msvc*:contains(QMAKE_TARGET.arch, x86_64):{
message( Building for 64 bit)
}
How can I get a list of the widgets added to a layout?
In order to get a list of the widgets added to a layout, then you can loop over the layout items using QLayout::count() http://doc.qt.io/qt-5/qlayout.html#count and QLayout::itemAt() http://doc.qt.io/qt-5/qlayout.html#itemAt and then if the the item is a QWidgetItem http://doc.qt.io/qt-5/qwidgetitem.html, you can add it's widget() http://doc.qt.io/qt-5/qwidgetitem.html#widget to a list.
See the following example for an illustration:
#include <QtWidgets>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget()
{
QVBoxLayout *layout = new QVBoxLayout(this);
QPushButton *button1 = new QPushButton(First button, this);
button1->setObjectName(First);
QPushButton *button2 = new QPushButton(Second button, this);
button2->setObjectName(Second);
QPushButton *button3 = new QPushButton(Third button, this);
button3->setObjectName(Third);
QPushButton *button4 = new QPushButton(Fourth button, this);
button4->setObjectName(Fourth);
layout->addWidget(button1);
layout->addWidget(button2);
layout->addWidget(button3);
layout->addWidget(button4);
for (int i = 0; i < layout->count();i++) {
if (QWidgetItem *myItem = dynamic_cast <QWidgetItem*>(layout->itemAt(i))) {
myList << myItem->widget();
}}
for (int i = 0; i < myList.count(); i++)
{
QWidget *wid = qobject_cast <QWidget*>(myList.at(i));
if (wid)
qDebug() << wid->objectName();
}}
private:
QList<QWidget*>myList;
};
#include main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
Widget window;
window.show();
return app.exec();
}
How can I exclude user input for certain widgets when processing a long operation?
One approach could be to call
setEnabled(false)
on the widgets you want to exclude user input to, but this might cause some flashing in the GUI. Using a QProgressDialog http://doc.qt.io/qt-5/qprogressdialog.html could be another option.
In situations where the approaches above are not suitable, then another approach to achieve this could be to reimplement the eventFilter() http://doc.qt.io/qt-5/qobject.html#eventFilter for your widget. Then you can set a flag when processing your event and check for this flag in the event filter. If the flag is set, you can simply return true and stop the event for the widgets you don't want the user to access. When the flag is not set, you can simply call the base class.
The example below illustrates this approach.
#include <QtWidgets>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget()
{
disableMe = false;
QPushButton *button1 = new QPushButton(DISABLE ME, this);
button2 = new QPushButton(CLICK ME, this);
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(button1);
layout->addWidget(button2);
qApp->installEventFilter(this);
QTimer::singleShot(1000, this, SLOT(test1()));
connect(button1, SIGNAL(clicked()), this, SLOT(button1Slot()));
connect(button2, SIGNAL(clicked()), this, SLOT(button2Slot()));
}
bool eventFilter(QObject *object, QEvent *event)
{
if (object != button2 && disableMe) {
if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick ) {
return true;
}} else {
return QWidget::eventFilter(object, event);
}}
public slots:
void test1()
{
for (int i = 0; i < 10000; i++) {
qDebug() << something;
disableMe = true;
qApp->processEvents();
}
disableMe = false;
}
void button1Slot()
{
qDebug() << 1111111111111111111111111111111111111111111111111111111111;
}
void button2Slot()
{
qDebug() << 222222222222222222222222222222222222222222222222222222222222;
}
private:
QPushButton *button2;
bool disableMe;
};
#include main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
Widget window;
window.show();
return app.exec();
}
Why does the memory keep increasing when repeatedly pasting text and calling clear() in a QLineEdit?
When calling QLineEdit::clear() http://doc.qt.io/qt-5/qlineedit.html#clear, the linedit is storing the text in the undo/redo buffer and therefore the memory usage will increase as that increases.
To get around this, you can call
QLineEdit::setText( )
instead. In this case, the undo/redo history will be cleared and you will not get a memory increase
Is it possible to move the Qt directory to another directory after installation?
When Qt is installed, the path is hardcoded into the Qt binaries, therefore it will not work to move it to another directory out of the box. You can however create a qt.conf http://doc.qt.io/qt-5/qt-conf.html file and override the hard-coded paths that are compiled into the Qt library there.
This way the paths from the qt.conf file will be used instead of the ones hardcoded into the Qt binaries.
Another alternative, is to use the qpatch.exe program available here http://qt.gitorious.org/qt-creator/qt-creator/trees/master/src/tools/qpatch
The usage is:
qpatch files-to-patch-windows oldQtDir newQtDir
How can I prevent the font from scaling up when the DPI is increased?
In order to prevent the font size from increasing when the DPI is increased then you can call
setPixelSize(theSizeYouNeed)
on your font and set this to be the application's font. This will ensure that the font will not scale with the DPI. See the documentation on setPixelSize() http://doc.qt.io/qt-5/qfont.html#setPixelSize
The following example illustrates this approach:
#include <QtWidgets>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QFont font = qApp->font();
font.setPixelSize(8);
qApp->setFont(font);
QLabel label("Resolution dependent.");
label.show();
return app.exec();
}
How can I control whether a widget gets a focus frame or not on Mac?
Some widgets will have a focus frame by default on Mac when the widget gets focus, for example QListView http://doc.qt.io/qt-5/qlistview.html and QLineEdit http://doc.qt.io/qt-5/qlineedit.html, whereas some will not get a focus frame, for example QTextEdit http://doc.qt.io/qt-5/qtextedit.html. In order to change when this occurs there is an attribute that can be used - WA_MacShowFocusFrame http://doc.qt.io/qt-5/qt.html#WidgetAttribute-enum. If you want a widget to have a frame then you can call:
widget->setAttribute(Qt::WA_MacShowFocusFrame);
to turn it off. It is just a case of passing false as the second argument like:
widget->setAttribute(Qt::WA_MacShowFocusFrame, false);
What are the minimum hardware requirements for Qt on the desktop?
We do not provide an official minimum hardware requirement list for Qt on the desktop, since it varies a lot on the the compiler used, the configuration and how you use Qt in your application.
Is there any way to compile the Qt source code and Qt applications with /clr flag?
We don't support building Qt or Qt applications with CLR directly. To integrate existing components you can use the Active Qt http://doc.qt.io/qt-5/activeqt.html framework, which allows integration of Active X and COM object in Qt applications.
Why is the warning QObject::startTimer: timers cannot be started from another thread issued when my worker thread is running?
The QThread http://doc.qt.io/qt-5/qthread.html class instance, like all QObject http://doc.qt.io/qt-5/qobject.html instances, lives in the thread in which you create it. The signals, slots and members of the custom thread will hence also belong to the thread where the custom thread was created and not to the custom thread itself.
In order for the signals, slots and members to have the right context/belong to the right thread, you should create a QObject subclass that contains this logic instead of a QThread subclass and simply instantiate an instance of this QObject subclass instead. QThread has a started() http://doc.qt.io/qt-5/qthread.html#started signal that you can connect to when you need to perform some initialization. To actually have your code run in the new thread context, you need to instantiate a QThread and assign your object to that thread using the moveToThread() http://doc.qt.io/qt-5/qobject.html#moveToThread function. This will ensure that the members get the custom thread as the context and not the GUI thread.
The following blog http://blog.qt.io/2010/06/17/youre-doing-it-wrong/ is written by one of the developers who created the threading classes and he suggests using the pattern explained above to get the right result.
How can I add buttons to the tabs of a QTabBar instead of having an icon/string?
It is not possible to add widgets to the tabbar (other than the close(x) button). Instead of using a QTabBar http://doc.qt.io/qt-5/qtabbar.html though, you could create a QWidget http://doc.qt.io/qt-5/qwidget.html that has the buttons in it and then you can make them all toggle buttons. That way when one is pushed then it can be used to change which widget is shown.
The example below illustrates how this can be done by subclassing QWidget and using a QButtonGroup http://doc.qt.io/qt-5/qbuttongroup.htmlto help with the exclusivity feature.
#include <QtWidgets>
class MyTabWidget : public QWidget
{
Q_OBJECT
public:
MyTabWidget(QWidget *parent = nullptr) : QWidget(parent)
{
QHBoxLayout *buttonsLayout = new QHBoxLayout;
buttonsLayout->setSpacing(0);
buttonsLayout->setMargin(0);
QButtonGroup *group = new QButtonGroup(this);
QPixmap pix(16, 16);
pix.fill(Qt::red);
QToolButton *button = new QToolButton;
button->setIcon(QIcon(pix));
button->setCheckable(true);
buttonsLayout->addWidget(button);
group->addButton(button, 0);
pix.fill(Qt::blue);
button = new QToolButton;
button->setIcon(QIcon(pix));
button->setCheckable(true);
buttonsLayout->addWidget(button);
group->addButton(button, 1);
pix.fill(Qt::green);
button = new QToolButton;
button->setIcon(QIcon(pix));
button->setCheckable(true);
buttonsLayout->addWidget(button);
buttonsLayout->addSpacing(100);
group->addButton(button, 2);
group->setExclusive(true);
connect(group, SIGNAL(buttonClicked(int)), this, SLOT(changeCurrent(int)));
stackedWidget = new QStackedWidget;
QLabel *red = new QLabel(This is the red widget);
QLabel *blue = new QLabel(This is the blue widget);
QLabel *green = new QLabel(This is the green widget);
stackedWidget->addWidget(red);
stackedWidget->addWidget(blue);
stackedWidget->addWidget(green);
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addLayout(buttonsLayout);
vbox->addWidget(stackedWidget);
setLayout(vbox);
}
public slots:
void changeCurrent(int idx)
{
stackedWidget->setCurrentIndex(idx);
}
private:
QStackedWidget *stackedWidget;
};
#include main.moc"
int main(int argc, char **argv)
{
QApplication a(argc, argv);
MyTabWidget tw;
tw.show();
return a.exec();
}
How can I expand all children of a specific modelindex in a QTreeView?
Currently Qt provides no function for this, but the following suggestion http://bugreports.qt.io/browse/QTBUG-10482 exists for adding such a function.
The example below illustrates how you can implement this functionality yourself.
#include <QtWidgets>
class TreeView : public QTreeView
{
public:
TreeView()
{
QStandardItemModel *model = new QStandardItemModel(this);
QStandardItem *parentItem = model->invisibleRootItem();
QStandardItem *myItem = new QStandardItem(child);
parentItem->appendRow(myItem);
QStandardItem *grandChild = new QStandardItem(hi);
myItem->appendRow(grandChild);
for (int i = 0; i < 200; ++i) {
QStandardItem *item = new QStandardItem(QString(item %0).arg(i));
grandChild->appendRow(item);
item->appendRow(new QStandardItem(QString(foo %0).arg(i)));
}
for (int i = 0; i < 4; ++i) {
QStandardItem *item = new QStandardItem(QString(item %0).arg(i));
myItem->appendRow(item);
}
for (int i = 0; i < 4; ++i) {
QStandardItem *item = new QStandardItem(QString(item %0).arg(i));
parentItem->appendRow(item);
parentItem = item;
}
setModel(model);
expandIt(model->indexFromItem(myItem));
}
public :
void expandIt(QModelIndex myIndex)
{
if (myIndex.isValid()) {
expand(myIndex);
}
QModelIndex nextIndex = indexBelow(myIndex);
while (nextIndex.isValid()){
if (myIndex.parent() == nextIndex.parent())
break;
expand(nextIndex);
nextIndex = indexBelow(nextIndex);
}}};
int main(int argc, char** argv)
{
QApplication app(argc, argv);
TreeView window;
window.show();
return app.exec();
}
How to upgrade Qt on Windows?
Note that the following is a guideline for a general upgrade process, depending on how you are using Qt and how you have installed it some of these steps may not apply or have to be done differently.
1) Uninstall the old version of Qt 2) Uninstall the old version of Qt-SDK 3) Install Qt or Qt-SDK 4) Install Qt vs-addin -- It automatically uninstalls the previous release 5) Update any instances of the Qt directory in your PATH environment variable 6) Clean all your projects by typing
nmake distclean (if using Visual Studio)
mingw32-make distclean (if using MinGW)
in your projects directories in the command prompt provided with Qt in the Start menu
7) Rerun qmake on all projects 8) Build all 9) If moc, your application, or other tools fail with side-by-side errors, check the System or Application events for details (Control Panel | Administrative Tools | Event Viewer). You are probably missing a dll and need to install a Microsoft update. If that doesn't work, use Dependency Walker (depends.exe) to locate the missing dll.
How can I have multiple rows in a QTabBar?
Qt does not provide a function that allows the tabs of a QTabBar http://doc.qt.io/qt-5/qtabbar.html to be arranged in multiple rows instead of one line and buttons to scroll the tabs. However, by reimplementing paintEvent() http://doc.qt.io/qt-5/qtabbar.html#paintEvent, mousePressEvent() http://doc.qt.io/qt-5/qtabbar.html#mousePressEvent and resizeEvent() http://doc.qt.io/qt-5/qtabbar.html#resizeEvent of the QTabBar class, one can get this functionality.
The attached example illustrates how this can be done. It leaves one problem open though, which is that only tabs in the first row will be highlighted when hovering over it.
See also the following report http://bugreports.qt.io/browse/QTBUG-2061 in the Bug Tracker.
How to toggle antialiasing for SVG rendering?
Qt's SVG module http://doc.qt.io/qt-5/qtsvg.html hardcodes antialiasing on, because this is what makes sense most of the time.
To be able to use rendering hints when rendering svg, one could use QtWebKit http://doc.qt.io/qt-5/qtwebkit.html and rely on the shape-rendering style property defined in the SVG specification http://www.w3.org/TR/SVG11/painting.html#RenderingProperties.
Here's an example:
#include <QtWidgets>
#include <QtWebKit>
class DemoWidget : public QWidget
{
Q_OBJECT
public:
DemoWidget(QWidget *parent = nullptr) : QWidget(parent)
, m_currentPage(0)
, m_widthSelector(new QSpinBox(this))
, m_antiAliasBox(new QCheckBox("Draw antialiased", this))
, m_showImageBox(new QCheckBox("Show on screen",this))
, m_saveToFileBox(new QCheckBox("Save to file", this))
, m_filePrefixEdit(new QLineEdit(this))
, m_startButton(new QPushButton("Start rendering", this))
{
QStringList args = qApp->arguments();
if (args.count() > 1) {
args.removeFirst();
foreach (QString url, args) {
if (!url.endsWith("svg"))
continue;
if (QFileInfo(url).exists())
m_urlList.append(QUrl::fromLocalFile(url));
else
m_urlList.append(QUrl(url));
}
} else {
m_urlList.append(QUrl("http://croczilla.com/bits_and_pieces/svg/samples/tiger/tiger.svg"));
}
setLayout(new QVBoxLayout);
layout()->setSpacing(1);
QString urlListText;
foreach (const QUrl url, m_urlList) {
urlListText.append("<b>" + url.toString() + "</b><br/>");
}
QLabel *l = new QLabel("list of Urls to be processed:<br/>" + urlListText);
l->setTextFormat(Qt::RichText);
layout()->addWidget(l);
m_widthSelector->setRange(100, 2000);
m_widthSelector->setSingleStep(100);
m_widthSelector->setValue(800);
layout()->addWidget(m_widthSelector);
m_filePrefixEdit->setText("image");
layout()->addWidget(m_filePrefixEdit);
layout()->addWidget(m_antiAliasBox);
layout()->addWidget(m_showImageBox);
layout()->addWidget(m_saveToFileBox);
connect(m_startButton, SIGNAL(clicked()), SLOT(startRendering()));
layout()->addWidget(m_startButton);
}
private slots:
void startRendering()
{
m_startButton->setDisabled(true);
foreach (const QUrl &url, m_urlList) {
QGraphicsWebView *view = new QGraphicsWebView;
view->setResizesToContents(true);
view->page()->setPreferredContentsSize(QSize(m_widthSelector->value(), m_widthSelector->value()));
connect(view, SIGNAL(loadFinished(bool)), SLOT(renderPage(bool)));
view->load(url);
}
}
void renderPage(bool loaded)
{
QGraphicsWebView *view = qobject_cast<QGraphicsWebView *>(sender());
if (!view) {
QMessageBox::critical(this, "Error", "an error occured");
return;
}
if (!loaded) {
QMessageBox::warning(this, "Loading problem", "There was an error while loading page "
+ view->url().toString());
return;
view->deleteLater();
}
QString antialiasValue;
if (!m_antiAliasBox->isChecked())
antialiasValue = "crispEdges";
else
antialiasValue = "geometricPrecision";
const QString js = QString("document.getElementsByTagName(\"svg\")[0].style.shapeRendering = \"%1\"").arg(antialiasValue);
view->page()->mainFrame()->evaluateJavaScript(js);
QImage image(view->page()->viewportSize(), QImage::Format_RGB32);
image.fill(-1);//white background
QPainter p(&image);
view->page()->mainFrame()->render(&p);
if (m_showImageBox->isChecked()) {
QLabel *label = new QLabel();
label->setAttribute(Qt::WA_DeleteOnClose);
QPixmap pix = QPixmap::fromImage(image);
label->setPixmap(pix);
label->show();
}
if (m_saveToFileBox)
image.save(m_filePrefixEdit->text() + QString::number(++m_currentPage) + ".png", "png");
if (m_currentPage == m_urlList.count()) {
m_startButton->setEnabled(true);
m_currentPage = 0;
}
view->deleteLater();
}
private:
int m_currentPage;
QList<QUrl> m_urlList;
QSpinBox *m_widthSelector;
QCheckBox *m_antiAliasBox;
QCheckBox *m_showImageBox;
QCheckBox *m_saveToFileBox;
QLineEdit *m_filePrefixEdit;
QPushButton *m_startButton;
};
#include "main.moc"
int main( int argc, char** argv ){
QApplication app( argc, argv );
DemoWidget w;
w.show();
return app.exec();
}
When using jom I get an error stating the script file could not be created. How do I fix this?
If you get something like the following error when running jom:
Error: Can't create command script file
Then this can be caused by the fact that the* %TMP% *directory on your system is marked as read only even though you can write to it. This is related to a problem with Windows this article http://support.microsoft.com/kb/326549/en-us o has more information about. If you unmark the read-only flag then this should solve the problem.
How to allow an application to only access webpages from a certain host?
The attached example illustrates how you can subclass QNetworkAccessManager http://doc.qt.io/qt-5/qnetworkaccessmanager.html and reimplement createRequest() http://doc.qt.io/qt-5/qnetworkaccessmanager.html#createRequest to control which webpages that are shown.
How can I enable autoscrolling when dragging near the edges in a QScrollArea?
The attached example is a modified version of the qtVersion/examples/draganddrop/draggabletext example, where autoscrolling has been implemented. The autoScroll() function in the example checks whether we are dragging within the autoscroll margins and modifies the values of the scrollbars accordingly using setValue() http://doc.qt.io/qt-5/qabstractslider.html#value-prop.
Then in the dragMoveEvent(), we simply call the autoScroll() function.
How can I sort a view by locale?
You can set a QSortFilterProxyModel http://doc.qt.io/qt-5/qsortfilterproxymodel.html on your view and call setSortLocaleAware() http://doc.qt.io/qt-5/qsortfilterproxymodel.html#isSortLocaleAware-prop on the proxy model.
If you are not using a QTableView http://doc.qt.io/qt-5/qtableview.html or QTreeView http://doc.qt.io/qt-5/qtreeview.html, but a convenience class like QTableWidget http://doc.qt.io/qt-5/qtablewidget.html, then you need to subclass QTableWidgetItem http://doc.qt.io/qt-5/qtablewidgetitem.html and reimplement QTableWidgetItem::operator<() http://doc.qt.io/qt-5/qtablewidgetitem.html#operator-lt to perform sorting based on the locale.
You could use QString::localeAwareCompare() http://doc.qt.io/qt-5/qstring.html#localeAwareCompare-2 for the comparison,
i.e something like
bool operator< (const QTableWidgetItem &other) const
{
...
return (text().localeAwareCompare(other.text()) < 0);
...
}
How can I add spaces between the columns in a QTableWidget?
In order to get the spacing between the columns in the header, then you can set a stylesheet http://doc.qt.io/qt-5/stylesheet.html like the following:
setStyleSheet(QHeaderView::section:horizontal {margin-right: 2; border: 1px solid});
To get the spacing between the cells, you can subclass your view, call
setShowGrid(false)
iterate over its columns and rows and draw the grid yourself with the size you need. The example below illustrates this approach:
#include <QtWidgets>
class TableWidget : public QTableWidget
{
Q_OBJECT
public:
TableWidget()
{
setRowCount(10);
setColumnCount(5);
QTableWidgetItem *newItem = new QTableWidgetItem(An item);
setItem(0,0, newItem);
setStyleSheet(QHeaderView::section:horizontal {margin-right: 2; border: 1px solid});
}
void paintEvent(QPaintEvent *event)
{
QTableWidget::paintEvent(event);
QPainter painter(viewport());
int myHeight = horizontalHeader()->height();
int i = 0;
for (i = 0; i < columnCount(); i++) {
int startPos = horizontalHeader()->sectionViewportPosition(i);
QPoint myFrom = QPoint(startPos, 0);
QPoint myTo = QPoint(startPos, height());
painter.drawLine(myFrom, myTo);
startPos += horizontalHeader()->sectionSize(i) - 3;
myFrom = QPoint(startPos, 0);
myTo = QPoint(startPos, height());
painter.drawLine(myFrom, myTo);
}
for (i = 0; i < rowCount(); i++) {
int startPos = verticalHeader()->sectionViewportPosition(i);
QPoint myFrom = QPoint(0, startPos);
QPoint myTo = QPoint(width(), startPos);
painter.drawLine(myFrom, myTo);
startPos += verticalHeader()->sectionSize(i);
myFrom = QPoint(0, startPos);
myTo = QPoint(width(), startPos);
painter.drawLine(myFrom, myTo);
}}};
#include main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
TableWidget table;
table.setShowGrid(false);
table.show();
return app.exec();
}
How can I cross-compile Qt/Embedded with Phonon support?
In order to be able to have Phonon support then you will need to either obtain the following libraries already cross-compiled for the hardware that you wish to use it on or you need to cross-compile them yourself:
- libxml2 v2.7.7 or later
- libcheck v0.9.8 or later
- liboil v0.3.2 or later
- gstreamer v0.10.0 or later
- gst-plugins-base v0.10.0 or later
The following can be installed with Buildroot:
- glib v2.16 or later
- libpng (optional)
- libtiff (optional)
- libjpeg (optional)
For extra audio and video formats then you also need to cross-compile the following:
- gst-plugins-good v0.10.0 or later
- gst-plugins-ugly v0.10.0 or later
When it comes to building Qt with Phonon support it also requires that your toolchain includes the tool pkg-config. Phonon uses pkg-config to retrieve the location and build flags of its dependencies. Then you need to set your PKG_CONFIG_PATH environment variable to refer to the directories that contain your embedded libraries pkconfig files. You can then cross-compile Qt as normal by setting up the environment variables necessary so that all the include files and library files can be found.
When configuring Qt, just ensure that you have the options:
-glib -phonon -phonon-backend
included so that Phonon is configured for in this build of Qt.
"Why do I get the error QPrintDialog: Cannot be used on non-native printers when printing to PDF using QPrintDialog?"
QPrintDialog http://doc.qt.io/qt-5/qprintdialog.html can�� be used to print to PDFs on Windows, because on Windows a native print dialog is used and it has no knowledge of Qt�� PDF printer.
Why don't I get a vertical scrollbar when my table has 1 row and only parts of the row is shown?
The default scrollMode http://doc.qt.io/qt-5/qabstractitemview.html#ScrollMode-enum is set to QAbstractItemView::ScrollPerItem by default. So, when you only have one row it decides it does not need a scrollbar. Setting the scrollMode to QAbstractItemView::ScrollPerPixel should cause a scrollbar to show up also when having just one row.
Why don't the QDir functions accept files that begin with ':' ?
This is because the colon as the first character in a filename is reserved for our resource model, and we cannot change that. QDir::remove() http://doc.qt.io/qt-5/qdir.html#remove for example will delete files starting with if passed an absolute path, but not a relative one. Instead you can try prepending ./ to your relative filename, that should make it work.
How can I programatically uncheck all buttons that have autoExclusive set to true?
When the autoExclusive http://doc.qt.io/qt-5/qabstractbutton.html#autoExclusive-prop property is enabled, checkable buttons that belong to the same parent widget behave as if they were part of the same exclusive button group. In an exclusive group, the user cannot uncheck the currently checked button by clicking on it; instead, another button in the group must be clicked to set the new checked button for that group. The same is true when unchecking the button programmatically.
To get around this, then you can e.g enable and disable the autoexclusive property for the currently checked button. See the following example for an illustration:
#include <QtWidgets>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget()
{
QVBoxLayout *layout = new QVBoxLayout(this);
button1 = new QPushButton(First, this);
button2 = new QPushButton(Second, this);
button3 = new QPushButton(Third, this);
layout->addWidget(button1);
layout->addWidget(button2);
layout->addWidget(button3);
button1->setCheckable(true);
button1->setAutoExclusive(true);
button2->setCheckable(true);
button2->setAutoExclusive(true);
button3->setCheckable(true);
button3->setAutoExclusive(true);
button3->setChecked(true);
QTimer::singleShot(1000, this, SLOT(testSlot()));
}
public slots:
void testSlot()
{
button1->setChecked(false);
button2->setChecked(false);
button3->setAutoExclusive(false);
button3->setChecked(false);
button3->setAutoExclusive(true);
}
private:
QPushButton *button1;
QPushButton *button2;
QPushButton *button3;
};
#include main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
Widget window;
window.show();
return app.exec();
}
Is there a way that Qt can open a window containing a PDF file?
You have the following alternatives:
- This Qt Quarterly article http://doc.qt.io/qt-5/qq/qq27-poppler.html outlines how you can do this using the 3rd party application Poppler.
- You can use QDesktopServices::openUrl() http://doc.qt.io/qt-5/4.7/qdesktopservices.html#openUrl
- You can use ActiveQt http://doc.qt.io/qt-5/qt-activex.html to show a QAXWidget that represents an Adobe reader window and thus load the PDF into that.
You can use a dummy action for the title where you set the action to be disabled and then paint it in the enabled color. The example below illustrates this approach.
#include <QtWidgets>
class MyWidget : public QWidget
{
public: MyWidget(QWidget * parent = nullptr) : QWidget (parent)
{
QVBoxLayout *layout = new QVBoxLayout(this);
QPushButton *button = new QPushButton(Button);
QMenu *menu = new QMenu(Menu);
QPalette pal = menu->palette();
pal.setColor(QPalette::Disabled, QPalette::Text, pal.color(QPalette::Active, QPalette::Text));
QAction *action = new QAction(this);
menu->setPalette(pal);
action->setText(Title);
action->setEnabled(false);
menu->addAction(action);
menu->addSeparator();
menu->addAction(Action 1);
menu->addAction(Action 2);
menu->addSeparator();
menu->addAction(Action 3);
button->setMenu(menu);
layout->addWidget(button);
}};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyWidget widget;
widget.show();
return app.exec();
}
Is it possible to modify the titlebar in a QDockWidget?
The titlebar is privately implemented when the QDockWidget is docked. When the dockwidget is floating, it is using the native titlebar as documented here http://doc.qt.io/qt-5/qdockwidget.html#setTitleBarWidget
You have no control over the native titlebar, so you can�� modify the titlebar when the dockwidget is floating. If you need to do so, then you need to create a custom titlebar using setTitleBarWidget() from the link above.
If you only need to modify the titlebar when the QDockWidget is docked however, you can modify it using the style. See the documentation on QStyle::CC_TitleBar http://doc.qt.io/qt-5/qstyle.html#ComplexControl-enum
What is the usage of the qtlibinfix and qtnamespace configuration options?
qtnamespace http://doc.qt.io/qt-5/configure-options.html compiles Qt into a namespace and qtlibinfix modifies the names of the Qt dlls.
For example: qtlibinfix renames all the Qt dlls with the infix you have chosen:
configure -qtlibinfix CustomName
will result in the Qt dlls having names like QtGuiCustomName.dll.
qtnamespace wraps all of the Qt code in the namespace you have chosen, e.g:
configure -qtnamespace CustomName
so that you would be writing code like
CustomName::QWidget *widget = new CustomName::QWidget;
as a result.
How can I use a QObject (subclass) in qml?
The QML engine has no intrinsic knowledge of any class types. Instead the programmer must register the C++ types with their corresponding QML names. This can be done using qmlRegisterType() http://doc.qt.io/qt-5/qdeclarativeengine.html#qmlRegisterType. When having registered the type, you can use it in qml as shown in the following example:
- main.cpp*
#include <QtWidgets>
#include <QDeclarativeEngine>
#include <QDeclarativeView>
#include <QtDeclarative>
class MyObject : public QObject
{
Q_OBJECT
public:
MyObject()
{}
public slots:
QObject * getObject()
{
return new MyObject();
}
};
#include main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QDeclarativeView view;
qmlRegisterType<MyObject>(QtQuick, 1, 0, MyObject);
view.setSource(QUrl::fromLocalFile(c:/testOwnership/test.qml));
view.show();
return app.exec();
}
- test.qml*
import QtQuick 1.0
Rectangle {
id: page
width: 500; height: 200
color: lightgray"
MyObject
{
id: myObject
Component.onCompleted: {
print(completed... + myObject.getInfo);
var obj = myObject.getInfo();
}}}
How can I ensure that the widgets in my touch screen application have a minimum size?
You can use QApplication::setGlobalStrut() http://doc.qt.io/qt-5/qapplication.html#globalStrut-prop for this. This function sets the minimum size a widget can be, and is helpful when making an application more touch screen friendly.
Why does Qt uses 0 instead of NULL in its code?
This is just a matter of coding style. Qt code uses 0 because it is more c++ like than NULL. If you wish to use NULL in your code however, that's fine.
How can we reference dynamically created objects in qml?
The standard way of referencing an object in qml is through its id() http://doc.qt.io/qt-5/qdeclarativeintroduction.html#object-identifiers value. It is not possible to assign an id to an object however, so the id can't be used for referencing dynamically created objects. The id is part of the parsing context of the .qml file and only available inside that .qml file. The id is not accessible through JS or C++.
What you can do instead, is to create a property variant variable and then assign the javascript object to that variable. Something like:
property variant foo;
onSomethingHappened: {
theObject = getMeTheObject();
foo = theObject;
}
lets you access a JS created object as if it had been named, through a member property.
How can I disable compilation of some code for a certain platform?
You can use one of the global macros http://doc.qt.io/qt-5/qtglobal.html to determine which OS you are compiling for. The following code for example:
// OS is not Windows
#ifndef Q_OS_WIN32
// execute code
will only be compiled on non-Windows platforms.
How should I start learning Qt?
The easiest way to learn Qt is to install the Qt SDK http://www.qt.io/product/ and try out one of the many examples/demos/tutorials. It comes with a dedicated IDE called Qt Creator http://www.qt.io/product/ that gets you going with Qt in an instant.
It can also be helpful to take a look at the official Get Started guide http://doc.qt.io/qt-5/qt-4.7/gettingstartedqt.html in the Qt documentation. Also, the Qt Developer Network (this site) has a wiki, a broad selection of eLearning videos [developer.qt.nokia.com] and other resources that you can use.
There is also an official Qt book http://developer.qt.nokia.com/books/view/c_gui_programming_with_qt_4_2nd_edition_the_official_c_qt_book and a beginners series http://qt.nokia.com/learning/education/course-materials for teachers teaching Qt at universities.
If you would like class room based Qt training there are a variety of courses being held by Qt partners around the world every month. Schedule and course info can be found here http://qt.nokia.com/partners/training/course-schedule.
Qt does not support tooltips in menus by default. This is because menu and menu items should have self-explaining names and if the menu names are good enough, the tooltips are redundant. You can get around this however by subclassing QMenu and reimplementing QMenu::event() http://doc.qt.io/qt-5/qmenu.html#event to intercept the QEvent::ToolTip http://doc.qt.io/qt-5/qevent.html#Type-enum event and call
QToolTip::showText(helpEvent->globalPos(), activeAction()->toolTip());
to set the tooltip for the active action.
The following example illustrates how this can be done:
#include <QtWidgets>
class Menu : public QMenu
{
Q_OBJECT
public:
Menu()
{}
bool event (QEvent * e)
{
const QHelpEvent *helpEvent = static_cast <QHelpEvent *>(e);
if (helpEvent->type() == QEvent::ToolTip) {
// call QToolTip::showText on that QAction's tooltip.
QToolTip::showText(helpEvent->globalPos(), activeAction()->toolTip());
} else {
QToolTip::hideText();
}
return QMenu::event(e);
}
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow()
{
Menu *menu = new Menu();
menu->setTitle(Test menu);
menuBar()->addMenu(menu);
QAction *action1 = menu->addAction(First);
action1->setToolTip(First action);
action1->setStatusTip(First action);
QAction *action2 = menu->addAction(Second);
action2->setToolTip(Second action);
action2->setStatusTip(Second action);
QAction *action3 = menu->addAction(Third);
action3->setToolTip(Third action);
action3->setStatusTip(Third action);
setCentralWidget(new QTextEdit(this));
statusBar();
}
};
#include main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
Also, note that when a menu item is hovered, the QAction::statusTip() http://doc.qt.io/qt-5/qaction.html#statusTip-prop text will be displayed in the status bar, if there is one.
How can I do file handling in QML?
QML does not contain functionality for doing file handling. You can however implement this logic in C++ and expose it to QML as explained in detail in the Getting Started Programming with QML http://doc.qt.io/qt-5/gettingstartedqml.html tutorial.
How can I create a window that has no taskbar entry?
In order to create a window that has no taskbar entry, you can create a dummy widget that acts as a parent for a second widget and keep the dummy widget hidden. Then you can pass in the Window http://doc.qt.io/qt-5/qt.html#WindowType-enum flag to the second widget. The following example illustrates how this can be done:
#include <QtWidgets>
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QWidget w1;
QWidget *w2 = new QWidget(&w1, Qt::Window);
w2->resize(100,100);
w2->show();
return app.exec();
}
How can I use QML in a worker thread?
The QML engine and the rendering can only run in the GUI thread. The QML WorkerScript http://doc.qt.io/qt-5/qml-workerscript.html however allows you to run operations in new threads.
How can I iterate over all the children in my window?
You can iterate over all the children in your window using QObject::findChildren() http://doc.qt.io/qt-5/qobject.html#findChildren.
The example below illustrates how this can be done:
#include <QtWidgets>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow()
{
QWidget *wid1 = new QWidget(this);
wid1->setAutoFillBackground(true);
setCentralWidget(wid1);
QLineEdit *edit1 = new QLineEdit(wid1);
QPushButton *button1 = new
QPushButton(Click me to change color of all children, wid1);
QHBoxLayout *layout = new QHBoxLayout(wid1);
layout->addWidget(edit1);
layout->addWidget(button1);
QWidget *wid2 = new QWidget(wid1);
layout->addWidget(wid2);
QLineEdit *edit2 = new QLineEdit(wid2);
QPushButton *button2 = new QPushButton(wid2);
QVBoxLayout *layout2 = new QVBoxLayout(wid2);
layout2->addWidget(edit2);
layout2->addWidget(button2);
connect(button1, SIGNAL(clicked()), this, SLOT(changeChildrenColor()));
}
public slots:
void changeChildrenColor()
{
qApp->setStyle(new QWindowsStyle());
QList<QWidget*> list = findChildren<QWidget *>();
QPalette pal = palette();
pal.setColor(QPalette::Window, Qt::red);
pal.setColor(QPalette::Base, Qt::blue);
pal.setColor(QPalette::Button, Qt::green);
foreach(QWidget *w, list) {
w->setPalette(pal);
}
}
};
#include main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
On the Mac the application title is displayed in the application menu and will by default be the name of the application. In order to change the name of the application title, you need to modify the Info.plist file which is part of your application. The easiest way to do this would be to copy the existing one from your application at:
application.app/Contents/Info.plist
and put it in your source directory. Then modify that file and add the lines:
<key>CFBundleName</key>
<string>Application Name Goes Here</string>
then add the following line to your pro file:
QMAKE_INFO_PLIST = Info.plist
After removing the existing application.app do:
qmake make
and this should change the name of the application title for you.
How can I export the contents of a QTableWidget to an excel workbook?
You can use ActiveQt http://doc.qt.io/qt-5/qt-activex.html in order to export the contents of a QTableWidget http://doc.qt.io/qt-5/qtablewidget.html to an excel workbook. The bulk of the work is done via the Excel functions made available to the ActiveX control.
The following example shows a basic implementation on how to do this.
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication a(argc, argv);
QAxObject *mExcelApp = new QAxObject(Excel.Application); // Start Excel
mExcelApp->setProperty(DisplayAlerts, QVariant(false));
mExcelApp->setProperty(UserControl, QVariant(false));
mExcelApp->setProperty(Visible, QVariant(true)); // Set it visible
QAxObject* vExcelWorkbooks = mExcelApp->querySubObject(Workbooks); // Get the workbooks
QAxObject* vExcelWorkbook = vExcelWorkbooks->querySubObject(Add()); // Add a new one (composed of 3 sheets)
QAxObject* vExcelWorksheets = vExcelWorkbook->querySubObject(Worksheets); // Get the sheets
QAxObject* vExcelWorksheet = vExcelWorksheets->querySubObject(Item(const QVariant& aVariant),QVariant(1)); // Get sheet number 2
vExcelWorksheet->dynamicCall(Activate());
vExcelWorksheet->setProperty(Name,QVariant(Survey Results));
QTableWidget tw(5,5);
for (int r=0;r<5;r++) {
for (int c=0;c<5;c++) {
tw.setItem(r, c, new QTableWidgetItem(QString(Row %1, Col %2).arg(r).arg(c)));
}
}
tw.show();
for (int i = 0; i < tw.rowCount(); i++) {
QVariantList vListOfValues;
for (int j = 0; j < tw.columnCount(); j++) {
QVariant vVariant;
qVariantSetValue(vVariant, tw.item(i, j)->text());
vListOfValues << vVariant;
}
QAxObject* vRange = vExcelWorksheet->querySubObject(Range(const QVariant&, const QVariant&), QVariant(QString(A%1).arg(i+1)), QVariant(QString(E%1).arg(i+1)));
vRange->setProperty(Value, vListOfValues);
}
return a.exec();
}
How can I embed widgets in QML?
You can embed QWidget-based objects into QML using QGraphicsProxyWidget http://doc.qt.io/qt-5/qgraphicsproxywidget.html. There is an example showing how to do it here http://doc.qt.io/qt-5/declarative-cppextensions-qwidgets.html.
How can I resize the QMainWindow to the size of its central widget after removing the QDockWidgets?
In order to resize the QMainWindow http://doc.qt.io/qt-5/qmainwindow.html to the size of its central widget after removing the QDockWidgets http://doc.qt.io/qt-5/qdockwidget.html, you need to call QLayout::activate() http://doc.qt.io/qt-5/qlayout.html#activate on the layout to inform the QMainWindow that the layout has changed.
The following example illustrates how this can be done:
#include <QtWidgets>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow()
{
setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
dock1 = new QDockWidget(this);
QPushButton *button = new QPushButton(Click me, this);
button->setCheckable(true);
setCentralWidget(button);
button->setMaximumHeight(24);
addDockWidget(Qt::BottomDockWidgetArea, dock1);
connect(button, SIGNAL(toggled(bool)), this, SLOT(toggleDockWidget(bool)));
}
QSize sizeHint() const
{
return QSize(800, 24);
}
QSize minimumSizeHint() const
{
return QSize(800, 24);
}
public slots:
void toggleDockWidget(bool test)
{
if (test) {
removeDockWidget(dock1);
layout()->activate();
resize(sizeHint());
} else {
restoreDockWidget(dock1);
} test = !test;
}
private:
QToolBar *toolBar;
QDockWidget *dock1;
};
#include main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
MainWindow window;
window.resize(window.sizeHint());
window.show();
return app.exec();
}
In order to modify the context menu that lists dockwidgets and toolbars in QMainWindow http://doc.qt.io/qt-5/qmainwindow.html, you can reimplement QMainWindow::createPopupMenu() http://doc.qt.io/qt-5/qmainwindow.html#createPopupMenu and return a new QMenu http://doc.qt.io/qt-5/qmenu.html with the actions you would like. Alternatively, if you only want to add to the existing menu, you can get hold of that one by calling the base class implementation and add any action you want to it.
The example below illustrates how you can reimplement QMainWindow::createPopupMenu() and add an action to the existing menu.
#include <QtWidgets>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow()
{
QDockWidget *dock1 = new QDockWidget(this);
dock1->setWindowTitle(Dock 1);
dock1->setWidget(new QTextEdit(dock1));
QToolBar *tool = new QToolBar(this);
tool->setWindowTitle(Tool);
tool->addAction(Test action);
addDockWidget(Qt::TopDockWidgetArea, dock1);
addToolBar(tool);
setCentralWidget(new QTextEdit(this));
};
QMenu* createPopupMenu ()
{
QMenu *menu = QMainWindow::createPopupMenu();
menu->addAction(An added action);
return menu;
}
};
#include main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
How can I create new QObjects in QML?
In order to create new QObjects http://doc.qt.io/qt-5/qobject.html in QML, you can subclass QDeclarativeItem http://doc.qt.io/qt-5/qdeclarativeitem.html and implement your own painting and functionality like for any other QGraphicsObject http://doc.qt.io/qt-5/qgraphicsobject.html. Note that QGraphicsItem::ItemHasNoContents http://doc.qt.io/qt-5/qgraphicsitem.html#GraphicsItemFlag-enum is set by default on QDeclarativeItem because it does not paint anything; so you will need to clear this if your item is supposed to paint anything (as opposed to being solely for input handling or logical grouping). If the item is not going to be visible, you can inherit from QObject directly instead of from QDeclarativeItem.
In order for QML to be able to create and manipulate this object, you need to register it with the QML engine using qmlRegisterType() http://doc.qt.io/qt-5/qdeclarativeengine.html#qmlRegisterType.
The example below illustrates how this can be done.
main.cpp
#include <QtWidgets>
#include <QtDeclarative>
class Circle: public QDeclarativeItem
{
Q_OBJECT
public:
Circle()
{
setFlag(QGraphicsItem::ItemHasNoContents, false);
}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override
{
painter->drawEllipse(QRect(10, 20, 80, 60));
}
};
#include main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
qmlRegisterType<Circle>(MyCircle, 1, 0, Circle);
QDeclarativeView view;
view.setSource(QUrl::fromLocalFile(test.qml));
view.resize(200, 200);
view.show();
return app.exec();
}
test.qml
import MyCircle 1.0
import QtQuick 1.0
Item {
width: 100; height: 100
Circle {
id: ellipse
anchors.centerIn: parent
}
}
The Defining New QML elements documentation http://doc.qt.io/qt-5/qtbinding.html#defining-new-qml-elements contains more information on this and so does this tutorial http://doc.qt.io/qt-5/declarative-tutorials-extending-chapter1-basics.html.
How can I add elements created in QML to a QGraphicsView ?
In order to add elements created in QML to a QGraphicsView http://doc.qt.io/qt-5/qgraphicsview.html, you can create a QDeclarativeComponent http://doc.qt.io/qt-5/qdeclarativecomponent.html which loads the QML code and then create an instance of this component using create() http://doc.qt.io/qt-5/qdeclarativecomponent.html#create. For example:
QDeclarativeEngine engine;
QDeclarativeComponent component(&engine);
component.setData(import QtQuick 1.0\nText { text: \Hello world!\ }, QUrl());
QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(component.create());
Since QDeclarativeItem http://doc.qt.io/qt-5/qdeclarativeitem.html is a QGraphicsObject http://doc.qt.io/qt-5/qgraphicsobject.html you can add it to your QGraphicsScene http://doc.qt.io/qt-5/qgraphicsscene.html.
The following example illustrates how this can be done.
main.cpp
#include <QtWidgets>
#include <QtDeclarative>
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QDeclarativeEngine engine;
QDeclarativeComponent component(&engine);
component.loadUrl(QUrl::fromLocalFile(test.qml));
QDeclarativeItem *item = qobject_cast <QDeclarativeItem *>(component.create());
QGraphicsView view;
QGraphicsScene *scene = new QGraphicsScene(&view);
view.setScene(scene);
scene->addItem(item);
view.show();
return app.exec();
}
test.qml
import QtQuick 1.0
Rectangle {
width: 100
height: 100
color: red"
border.color: black"
border.width: 5
radius: 10
}
Is there any way to include a .qrc file in another .qrc file?
It is not possible to include a .qrc file in another .qrc file. Instead, you can use .pri files to get around this. Those .pri files can then reference one or more resource files and/or include other .pri files. In your .pro file, you then include() http://doc.qt.io/qt-5/qmake-function-reference.html#include-filename the .pri file you want, and all the resources in the tree of resource .pri files will be added to your project.
How can I pass a value or a string from QML to C++?
In order to pass a value or a string from QML to C++, you can create a function that is callable from QML by marking it with Q_INVOKABLE http://doc.qt.io/qt-5/qobject.html#Q_INVOKABLE as documented here http://doc.qt.io/qt-5/qml-extending.html#methods. Slots are callable from QML without the need for the Q_INVOKABLE macro. Then you can make the class containing the function or slot accessible in QML by calling QDeclarativeView::rootObject() http://doc.qt.io/qt-5/qdeclarativeview.html#rootContext and simply call the function or the slot with the appropriate value from QML and it will be handled on the C++ side .
The following example illustrates how this can be done.
main.cpp
#include <QtWidgets>
#include <QtDeclarative>
class MyObject : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE void cppMethod(const QString &msg)
{
qDebug() << Called the C++ method with << msg;
}
public slots:
void cppSlot(int number) {
qDebug() << Called the C++ slot with << number;
}
};
#include main.moc"
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QDeclarativeView view;
MyObject MyObject;
view.rootContext()->setContextProperty(myObject, &MyObject);
view.setSource(QUrl::fromLocalFile(main.qml));
view.resize(200,200);
view.show();
return app.exec();
}
main.qml
import QtQuick 1.0
Rectangle {
width: 100; height: 100
color: blue"
MouseArea {
anchors.fill: parent
onClicked: {
myObject.cppMethod(Hello from QML)
myObject.cppSlot(37)
}
}
}
How can I create multiple toplevel windows in QML?
Currently Qt does not provide support for creating toplevel windows directly inside a QML application. To create multiple windows, you��l have to create multiple toplevel QDeclarativeViews (or another widget). However, you can check out the following project http://blog.qt.io/2011/08/26/toplevel-windows-and-menus-with-qt-quick/ on Qt Labs which provides functionality for creating toplevel windows directly in QML.
How can I allow external objects to directly access and modify child objects in a component?
In order to allow external objects to modify and access child objects in another component, you can use Property Aliases http://doc.qt.io/qt-5/4.7-snapshot/propertybinding.html#property-aliases. Property Aliases allow you to make properties in a component directly accessible when importing the component.
The following example illustrates how this can be done:
main.cpp
#include <QtWidgets>
#include <QtDeclarative>
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QDeclarativeView view;
view.setSource(QUrl::fromLocalFile(main.qml));
view.resize(800,200);
view.show();
return app.exec();
}
main.qml
import QtQuick 1.0
Rectangle {
width: 740; height: 150
Column {
anchors.fill: parent; spacing: 20
Text {
text: Example that illustrates how to allow external objects to directly modify and access child objects in a component"
font.pointSize: 12; anchors.horizontalCenter: parent.horizontalCenter
}
}
Row {
anchors.verticalCenter: parent.verticalCenter
Button { onClicked: { buttonLabel = New value for Button } }
Button { onClicked: { buttonLabel = New value for Button }}
Button { onClicked: { buttonLabel = New value for Button }}
}
}
Button.qml
import QtQuick 1.0
Rectangle {
id: root;
property alias buttonLabel: label.text
signal clicked()
width: 120
height: 30
color: mouse.pressed ? lightgray : white"
radius: 4
border.width: 1
border.color: gray"
MouseArea {
id: mouse
anchors.fill: parent
onClicked: root.clicked();
}
Text {
id: label
anchors.centerIn: parent
text: Click Me"
}
}
Why do I get metatype errors when trying to use my custom class with QVariant and properties?
In order to use a custom type in QVariant http://doc.qt.io/qt-5/qvariant.html it is necessary to make the custom type known to QMetaType http://doc.qt.io/qt-5/qmetatype.html using Q_DECLARE_METATYPE http://doc.qt.io/qt-5/qmetatype.html#Q_DECLARE_METATYPE. If this is not done, you will get metatype errors similar to the following:
error C2039: 'qt_metatype_id' : is not a member of 'QMetaTypeId<T>'
with
[
T=MyValue
]
If you also need to use the custom type with QObject::property() http://doc.qt.io/qt-5/qobject.html#property or in queued connections you need to register the type using qRegisterMetaType() http://doc.qt.io/qt-5/qmetatype.html#qRegisterMetaType as well. Otherwise, you will run into errors like the following:
QMetaProperty::read: Unable to handle unregistered datatype 'MyValue' for property 'QTestObj::Test'
The example below shows how this can be implemented.
#include <QtWidgets>
class MyValue
{
public:
MyValue(double number)
{
number1 = number;
}
MyValue()
{}
double toDouble() { return number1; }
private:
double number1;
};
Q_DECLARE_METATYPE(MyValue);
class QTestObj : public QObject
{
Q_OBJECT
Q_PROPERTY(MyValue Test READ getTest WRITE setTest)
public:
QTestObj(QObject* parent = nullptr) : QObject(parent) , test(5.0)
{}
MyValue getTest() const { return test; }
void setTest(MyValue newValue) { test = newValue; }
private:
MyValue test;
};
#include main.moc"
int main(int argc, char *argv[])
{
QTestObj Test;
qRegisterMetaType<MyValue>(MyValue);
qDebug() << Value of property 'Test' is equal << Test.property(Test).value<MyValue>().toDouble();
qDebug() << Trying set new value for property 'Test'...;
if (Test.setProperty(Test, QVariant::fromValue<MyValue>(0.25)))
{
qDebug() << New value is set successfully.;
} else {
qDebug() << Method setPropery failed!;
}
qDebug() << Test.property(Test).value<MyValue>().toDouble();
return 0;
}
How can I change the column width of a QTableWidget when it is being resized?
You can set the headers ResizeMode http://doc.qt.io/qt-5/qheaderview.html#ResizeMode-enum to be QHeaderView::Stretch, then the columns and rows will resize when you resize the widget.
The following example illustrates how this can be done.
#include <QtWidgets>
class TableWidget : public QTableWidget
{
Q_OBJECT
public:
TableWidget()
{
setRowCount(10);
setColumnCount(5);
QTableWidgetItem *newItem = new QTableWidgetItem(An item);
setItem(0,0, newItem);
horizontalHeader()->setResizeMode(QHeaderView::Stretch);
verticalHeader()->setResizeMode(QHeaderView::Stretch);
}
};
#include main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
TableWidget window;
window.resize(400,400);
window.show();
return app.exec();
}
How can I make a window unmovable?
It is the window manager that controls the moving of the window through the titlebar and Qt has no influence over that unfortunately. You can use one of the following approaches to prevent the window from being moved though:
- Create a window without a titlebar by specifying the Qt::FramelessWindowHint flag
- Create your own custom titlebar. This will give you full control over the titlebar and allow you to stop it from being moved.
How can I remove the plus/minus sign from a QTreeWidget and still be able to expand the items?
You can modify the drawing of the branches in the style to not draw the minus/plus sign. Reimplement drawPrimitive() http://doc.qt.io/qt-5/qstyle.html#drawPrimitive and remove the QStyle::State_Children http://doc.qt.io/qt-5/qstyle.html#StateFlag-enum state from the QStyleOption http://doc.qt.io/qt-5/qstyleoption.html and the minus/plus sign will be gone.
The example below illustrates how this can be done:
#include <QtWidgets>
class Style : public QWindowsStyle
{
public:
Style()
{}
void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w) const
{
QStyleOption* op = const_cast<QStyleOption*>(opt);
op->state &= ~ QStyle::State_Children;
QWindowsStyle::drawPrimitive(pe, op, p, w);
}
};
class TreeWidget : public QTreeWidget
{
Q_OBJECT
public:
TreeWidget()
{
QTreeWidgetItem *root = invisibleRootItem();
QTreeWidgetItem *firstItem = new QTreeWidgetItem(root);
firstItem->setText(0,First);
QTreeWidgetItem *secondItem = new QTreeWidgetItem(firstItem);
secondItem->setText(0,Second);
QTreeWidgetItem *thirdItem = new QTreeWidgetItem(secondItem);
thirdItem->setText(0,Third);
}
};
#include main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
TreeWidget tree;
tree.setStyle(new Style());
tree.show();
return app.exec();
}
How can I move entire rows in my QTableWidget?
You can move entire rows in a QTableWidget http://doc.qt.io/qt-5/qtablewidget.html by calling setMovable() http://doc.qt.io/qt-5/qheaderview.html#setMovable on the vertical header.
See the following example for an illustration:
#include <QtWidgets>
int main( int argc, char** argv )
{
QApplication a( argc, argv );
QTableWidget table(4,4);
for (int row = 0; row < 4; row++) {
for(int col = 0; col < 4; col++) {
QTableWidgetItem *item = new QTableWidgetItem(QString(Row%1 Col%2).arg(row).arg(col));
item->setFlags(item->flags() | Qt::ItemIsSelectable);
table.setItem(row,col,item);
}
}
table.verticalHeader()->setMovable(true);
table.show();
return a.exec();
}