Replace QRadioButton's text with image - qt

I have two radio buttons. I'd like to replace the controls' text (not the indicator) with images/icons. How can I do this?
With a QLabel I do this by using setPixmap(); the method is not available in QRadioButtons.
I tried
setStyleSheet("background-image: url(./images/img.png); background-repeat: no-repeat;");
but the image is set as the background of the entire control (indicator + label), not just the label.
Any idea?

Why not use Qt resource system to add the desired icons and then use the buttons setIcon method to assign them an icon? Here's an example :
#include "widget.h"
#include <QIcon>
Widget::Widget(QWidget *parent) : QWidget(parent) {
lyt = new QVBoxLayout;
grpBx = new QGroupBox("Radio buttons");
QVBoxLayout* lyt_btns = new QVBoxLayout;
grpBx->setLayout(lyt_btns);
rBtn1 = new QRadioButton("");
rBtn2 = new QRadioButton("");
lyt_btns->addWidget(rBtn1);
lyt_btns->addWidget(rBtn2);
rBtn1->setIcon(QIcon(":/spoon.png"));
rBtn1->setIconSize(QSize(10,10));
rBtn2->setIcon(QIcon(":/fork.png"));
rBtn2->setIconSize(QSize(10,10));
lyt->addWidget(grpBx);
setLayout(lyt);
}
Widget::~Widget() {
delete lyt;
delete rBtn1;
delete rBtn2;
delete grpBx;
}
PS if you don't know what is and how to use the Qt ressource system here some tips:
Choose the Edit view in Qt Creator.
Right-click on the project, then choose Add New.... In the New File dialog that
opens, click on Qt under Files and Classes, and click on Qt Resource file.
Name the file resources.
Add it to the current project.
If resources.qrc isn't already open in the editor, double-click on it in the
solution pane. The resource file editor will appear.
Click on Add, choose Add prefix, and make the prefix /.
Click on Add again, then on Add Files, and choose your icon.
After that you've added ressources to your .qrc file, the application can access those files by simply using the colon symbol ":" + the prefix specified in step 6 and then the ressource name (as shown in the example)
Please see : The Qt Resource System documentation

Related

SIGSEGV when adding widget in Qt

I implemented example (chapter 2) from "Mastering Qt 5" book but the code crashes when adding widget to centralWidget's layout:
ui->centralWidget->layout()->addWidget(&mCpuWidget)
I suspect that the centralWidget does not have layout, hence it crashes but I don't know how to fix that?
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
mCpuWidget(this)
{
ui->setupUi(this);
SysInfo::instance().init();
ui->centralWidget->layout()->addWidget(&mCpuWidget);
}
Here are two more classes which might help figure out the problem. Some of you might have the book too with all of the code (hence I mentioned it).
CpuWidget::CpuWidget(QWidget* parent):
SysInfoWidget(parent),
mSeries (new QPieSeries (this))
{
mSeries->setHoleSize(0.35);
mSeries->append("CPU Load", 30.0);
mSeries->append("CPU Free", 70.0);
QChart* chart = chartView().chart();
chart->addSeries(mSeries);
chart->setTitle("CPU Average Load");
}
This class creates and sets layout (QVBoxLayout)
SysInfoWidget::SysInfoWidget(QWidget *parent, int startDelayMs, int updateSeriesDelayMs) :
QWidget(parent),
mChartView(this)
{
mRefreshTimer.setInterval(updateSeriesDelayMs);
connect(&mRefreshTimer, &QTimer::timeout,
this, &SysInfoWidget::updateSeries);
QTimer::singleShot(startDelayMs,
[this] {mRefreshTimer.start();});
mChartView.setRenderHint(QPainter::Antialiasing);
mChartView.chart()->legend()->setVisible(false);
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(&mChartView);
setLayout(layout);
}
I'm the co-author of the book "Mastering Qt 5" !
I guess your suspicion about the layout is correct:
ui->centralWidget->layout()->addWidget(&mCpuWidget);
Without any layout defined the returned item is null so you can't call the method layout().
If you have some errors during your learning you should refer to the final source code hosted on github here: https://github.com/PacktPublishing/Mastering-Qt-5
Take a look to the the file "Mastering-Qt-5/Chapter_02/MainWindow.ui":
<ui version="4.0">
...
<widget class="QWidget" name="centralWidget">
<layout class="QHBoxLayout" name="horizontalLayout"/>
</widget>
...
</ui>
As you can see for this project, a horizontalLayout of type QHBoxLayout is defined in the centralWidget. You can easily edit a ".ui" file with a text editor from Qt Creator with the following steps:
Right-click on "MainWindow.ui" in the Project hierarchy view
Select "Open-With"
Finally "Plain text editor"
Select "Form editor" when you want to come back to the WYSIWYG editor.
As suggested in other answers, the way to do it from C++ with the following line is also correct:
ui->centralWidget->setLayout(new QHBoxLayout());
Thank you for highlighting the lack of information about the layout here. I created an issue to add an errata about this topic.
Unless I have missed something in the code you have provided you haven't actually set your central widget. By default calling QMainWindow::centralWidget() returns a NULL pointer. You need to first call QMainWindow::setCentralWidget(QWidget* yourCentralWidget) before you call it. And yes, you also need to add a layout to it if you want to use layout()->addWidget(...). You can create an instance of a generic QWidget, set its layout, set is a central widget and then work with it.
You can fix your problem either by adding a layout in C++:
ui->setupUi(this);
SysInfo::instance().init();
ui->centralWidget->setLayout(new QVBoxLayout()); // Or any other layout class
ui->centralWidget->layout()->addWidget(&mCpuWidget);
Or in the UI Designer by using those buttons:
Note that for the buttons to be active you need to have at least 1 widget in your central widget and then select your central widget. You can then write:
ui->setupUi(this);
SysInfo::instance().init();
// One way
ui->centralWidget->layout()->addWidget(&mCpuWidget);
// Another way
ui->layout->addWidget(&mCpuWidget);
Finally you could also move your CpuWidget to the ui file using the "Promote to..." option in the contextual menu. In this case you would not need mCpuWidget but you could access it using something like ui->cpuWidget.
For more info read the Qt Designer manual:
Using Layouts in Qt Designer
Using Custom Widgets with Qt Designer

How to get an icon associated with a certain file type using PyQt/PySide?

I have a QListView that adds a newly added file to a folder using QFileSystemWatcher, however I also want QListView to show the icon for that filetype just as QFileSystemModel would add. I do not want to add any custom icon only the icon that Operating system has registered for the specific to file type.
I just figured out how to achieve this using the code below:
fileInfo = QtCore.QFileInfo(path)
iconProvider = QtGui.QFileIconProvider()
icon = iconProvider.icon(fileInfo)

Javascript blocks are not supported in a Qt Quick UI form

I'm trying to do a very simple Qt Quick application.
Qt Creator automatically creates a MainForm.ui.qml file, in which I put my UI components, such as a TextField.
When the content of this TextField is changed, I want to call a invokable method of a C++ QObject.
Here is what I did :
TextField {
...<snip>...
onTextChanged: {
var Result = myCppObj.doStuff(text)
lblOutput.text = Result
}
}
When I start my application, it is working fine.
But the doStuff(text) call is underlined in red, showing the following message :
Javascript blocks are not supported in a Qt Quick UI form (M223).
And I cannot edit my UI with the designer tool any more.
Any idea why and how to solve this ?

How to build widgets from any .ui files created by QtDesigner

I would like to make something like GUI creator which takes an ui file and creates widgets in it, and show in a window.
So I have created a button on click I use QFileDialog to get a file.
And then I would like to use the ui file from QFileDialog to create that gui/widgets and show in a window.
I have tried QFormbuilder, but it always gives me compile error “undefined reference to `QFormBuilder::QFormBuilder()’”
Is there a way to do it in qt5?
Any help appreciated
From documentation of QUiLoader:
QUiLoader loader;
QFile file(":/forms/myform.ui");
file.open(QFile::ReadOnly);
QWidget *myWidget = loader.load(&file, this);
file.close();
I have solved the problem.
Actually I was missing QFormbuilder module in my .pro file. So I have just added them, and it is working fine.

What determines the default title for a QMessageBox?

I want to change the default QMessageBox title to something else, so that I don't have to call setWindowTitle for every individual message box.
How is the default window title chosen?
Best way to do this is to subclass QMessageBox, e.g.:
class MyMessageBox : public QMessageBox
{
MyMessageBox() //<-- default constructor
{
setWindowTitle("Default title goes here"); //QMessageBox function
}
};
Use MyMessageBox everywhere in the code.
You could instead add a TARGET in the .pro file. e.g. add this line to the .pro file:
TARGET = MyApp
Thus "MyApp" will be applied both as the executable file name and also as default value for windowTitle of all QMessageBoxes in the entire project.
You don't need to call setWindowTitle method while you can title when you instance the QMessageBox object.
On Windows developing with VC2008 it takes the name from the project. Change the name of the project and it will change the title.

Resources