I've been working on my first gui application. I need to store some values for everything to function so I decided to use QSettings and learn how to use windows registry. I have found an example for the size and position so I have do have a slight grasp on what is going on here, but for some reason I cannot get it to work when I try on my own. I have been struggling with this for a few weeks now and just cant find any good references on how to add my own strings to the registry. Below is all the pertinent code needed for this to happen. Any help or point in the right direction will be greatly appreciated. Also I have the fundamentals of Qt 4 or something like that but it was not that much help to me in this instance, so if anyone has any quick references to some quality related articles or more comprehensive works on the more advanced QT topics i would be interested to hear them, not to get to far off the topic at hand though, I'm sure there's tons of good books out there.
MainWindow.cpp
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
createActions();
createMenus();
createMainWidget();
createIcons();
createDocks();
createStatusBar();
setMinimumSize(950,600);
setWindowTitle(tr("Black Ops Toolbox: Vrs. 0.0.0.12.01"));
QString defaultDirPath = "";
readSettings();
}
void MainWindow::readSettings()
{
QSettings settings;
QPoint pos = settings.value("pos", QPoint(25,25)).toPoint();
move(pos);
QSize size = settings.value("size",QSize(1200,900)).toSize();
resize(size);
QString defaultDirPath = settings.value("defaultDirPath", QString("c:/programfiles/")).toString();
}
void MainWindow::writeSettings()
{
QSettings settings;
settings.setValue("pos",pos());
settings.setValue("size",size());
settings.setValue("defaultDirPath", QVariant(QString *defaultDirPath).toString());
}
void MainWindow::closeEvent(QCloseEvent *event)
{
writeSettings();
}
MainWindow.h
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
protected:
void closeEvent(QCloseEvent *event);
private:
void createActions();
void createActionEvents();
void createMenus();
void createMainWidget();
void createIcons();
void createDocks();
void createStatusBar();
void readSettings();
void writeSettings();
QString *defaultDirPath;
};
I really did not use QSettings yet, but from documentation it seems that in your code some information misses.
In particular, you must give (from Basic usage section), organization name and application name, using the QSettings constructor, like
QSettings settings("MySoft", "Star Runner");
or using QCoreApplication settings and then the default QSettings constructor
QCoreApplication::setOrganizationName("MySoft");
QCoreApplication::setOrganizationDomain("mysoft.com");
QCoreApplication::setApplicationName("Star Runner");
...
QSettings settings;
Have you tried one of these methods to create your QSettings?
Related
I have been trying to add a QToolBar inside a QTabWidget in order to achieve something like the image below, so that everytime I add a new QTabWidget I have also a related QToolBar inside it.
Everything seems to work fine, I create a QAction to link it to the QTabWidget and according to this post it seems to be possible to do that but the problem is that when I compile nothing shows up as shows below:
Below is what I have done so far:
mainwindow.h
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void onChangeTab(int index);
void newTab();
void closeTab(const int &index);
private slots:
void on_addTabBtn_clicked();
void on_tabWidget_tabCloseRequested(int index);
private:
Ui::MainWindow *ui;
QAction *addTab1;
QToolBar *mToolBar1;
QAction *addIconToolBar1;
};
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->tabWidget->clear();
ui->tabWidget->setTabsClosable(true);
ui->tabWidget->addTab(new QLabel("Add"), QString("Add"));
ui->toolBar->setContextMenuPolicy(Qt::ActionsContextMenu);
mToolBar1 = new QToolBar;
addIconToolBar1 = new QAction;
addIconToolBar1->setIcon(QIcon("qrc:/cardio.png"));
ui->toolBar->addWidget(mToolBar1);
ui->toolBar->addAction(addIconToolBar1);
connect(ui->addTabBtn, &QPushButton::clicked, this, [&] { ui->tabWidget->addTab(new QLabel("Add"), QString("Add")); });
connect(ui->tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_addTabBtn_clicked()
{
int index = 0;
if(index == this->ui->tabWidget->count() - 1) {
newTab();
}
}
void MainWindow::on_tabWidget_tabCloseRequested(int index)
{
ui->tabWidget->removeTab(index);
}
I tried to solve the problem in many ways and researched what the cause might be. I came across several references such as this one, which is the most important I found as the user seems to be doing it but there is no reference to documentation or no example to code to understand/study through.
Thanks for pointing to the right direction to solve this issue.
You can simply do something like this, and it really works.
QToolBar *toolbar=new QToolBar("toolbar",ui->tab);
toolbar->addAction("action1");
toolbar->addAction("action2");
enter image description here
I don't see where you are trying to add Toolbar to your TabWidget...
You must define Layout, add your toolbar to that layout and finally set layout to your tabWidget.
Try to do something like this, in your mainwindow constructor.
QHBoxLayout* tabWidgetLayout = new QHBoxLayout;
tabWidgetLayout->addWidget( your toolbar);
tabwidget->setLayout(tabWidgetLayout);
Also don't forget to include QHBoxLayout's header.
Even if other answers may seem to work, this is actually the right way to do what you asked for.
I was facing one issue with the Widget which is integrated in the QQuickPaintedItem class. When I have Widget integrated in the QQuickPaintedItem, QWidget::isVisible will return false. If I tried to set QWidget::setVisible(true) then it will open another window, which I do not want in my scenario.
Is there any way to get QWidget::isVisible return true so that my child widgets (In my actual scenario, we have 5 layer of parent child hierarchy) will also works fine when I say QWidget::show()?
I have created the scenario similar to it as below.
Header file:
class MyItem: public QQuickPaintedItem{
Q_OBJECT
public:
explicit MyItem(QQuickItem *parent = 0);
void paint(QPainter *painter);
~MyItem();
Q_INVOKABLE void initButton();
protected:
virtual void mousePressEvent( QMouseEvent* event );
private:
QPushButton* bp;
};
source file:
MyItem::MyItem(QQuickItem *parent)
: QQuickPaintedItem(parent)
{
bp = new QPushButton("Hello");
}
MyItem::~MyItem()
{
delete bp;
}
void MyItem::paint(QPainter *painter){
bp->render(painter, QPoint(), QRegion(), QPushButton::DrawWindowBackground | QPushButton::DrawChildren);
}
void MyItem::mousePressEvent( QMouseEvent* event )
{
qDebug() << Q_FUNC_INFO << bp->isVisible();
}
Thanks for help in advance...!!!
I don't know why you want to do this.
Qt do not support to embed a QWidget into a Qt Quick Item in Qt5(Qt Quick 2).
In your code, QWidget is a seperate Window, and you Qt Quick item is in it's own Window.
If you want your Qt Quick item behavior like a Button, you should use Qt Quick's Button control or write one yourself.
If you really want to embed a QWidget into Qt Quick's control tree, you can use Qt Quick 1(Qt4.7/8) instead. Check out QGraphicsProxyWidget's document.
I want to pass a string from a form that is opened by the first form to the first form.
I am new to C++.
Here is my code.
Form1.h // main form
#include "dialog.h"
namespace Ui {
class Form1;
}
class Form1 : public QMainWindow
{
Q_OBJECT
public:
explicit Form1(QWidget *parent = 0);
~Form1();
void refresh(QString str_local);
private slots:
void on_pushButton_clicked();
private:
Ui::Form1 *ui;
Dialog *dialog1;
};
// form1.cpp
void Form1::on_pushButton_clicked()
{
dialog1= new Dialog; //Create new form with other class
dialog1->show();
QObject::connect(dialog1, SIGNAL(change(str_remote)), this, SLOT(refresh(str_local))); //Connect when is emit signal cambia in the child form and pass the string to local function
}
void Form1::refresh(QString str_local)
{
qDebug() << "Back to main" << str_local;
ui->label->setText(str_local);
}
// dialog.h the second form that should pass the value to main form
...
class Dialog : public QDialog
{
Q_OBJECT
signals:
void change(QString s);
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private slots:
void on_pushButton_clicked();
private:
Ui::Dialog *ui;
};
// dialog.cpp
...
void Dialog::on_pushButton_clicked()
{
QString name;
name = ui->lineEdit->text();
emit change(name);
this->close();
}
I get the error:
No such signal Dialog::change(str_remote) in ../Format/form1.cpp:22 .
You have some strange code in here:
QObject::connect(dialog1, SIGNAL(change(str_remote)), this, SLOT(refresh(str_local)));
Since your class already inherits QObject indirectly, you can simply drop the scope specifier.
You probably aim for using the new compilation-time syntax signal-slot mechanism.
You have not marked your slot as slot in the header file.
You are trying to use the old signal/slot syntax with variable names for the signal and slot as opposed to the types.
Your signal is not using the good practice of const T& (i.e. constant reference).
You are specifying this explicitly, whereas it can be dropped. This is just admittedly personal taste.
You do not follow the Qt signal/slot naming convention, e.g. your signal is a verb rather adjective. It is also too generic, rather than "fooChanged" as the good practice goes.
There are other issues in your code as well, but this time I only focused on that one line. I would use this line with modern Qt and C++ programming principles in mind:
connect(dialog1, &Dialog::changed, (=)[const auto &myString] {
ui->label->setText(myString);
});
However, since this requires CONFIG += c++14, if your compiler does not support that (e.g. VS2010), you can go for this:
connect(dialog1, SIGNAL(change(const QString&)), this, SLOT(refresh(const QString&)));
I am new to Qt and almost every tutorial I find says to add the image to a QLabel using setPixmap(). Maybe this is the right way, but it doesn't feels to be, since using a label for a image seems to go beyond the purpose of a label.
Could anyone tell me if there is a "right way" or a special Class for this, or if the "Label way" is the right one, not just the simple one.
Using QLabel is the usual way to display an image in a QtWidgets-based UI. That might indeed feel a bit awkward, as QLabel's API is mostly concerned with text rendering. However, it does the job and there's no other class dedicated to only painting images. One could think of writing his own class (taking a QPixmap, reimplementing paintEvent(), sizeHint()), but that would only make sense to me if functionality is needed that QLabel lacks.
There are of course many other ways to paint an image, depending on the context, like images on buttons (QToolButton, QPushButton, ...), images in graphics scenes (QGraphicsScene/View) etc., but they all serve either more specialized or more complex use cases.
easiest way is to use a QLabel.in ImageViewer example
http://qt-project.org/doc/qt-4.8/widgets-imageviewer.html they use QLabel ..
another way
QGraphicsView view(&scene);
QGraphicsPixmapItem item(QPixmap("c:\\test.png"));
scene.addItem(&item);
Here is a simple class that isn't Label based. I suppose it depends on what you personally feel is the proper way to do it and what you need to do with it. I prefer implementing my own class so you can add on to it later(maybe you want to manipulate the image).
imagewidget.h
#ifndef IMAGEWIDGET_H
#define IMAGEWIDGET_H
#include <QPainter>
#include <QImage>
#include <QWidget>
QT_BEGIN_NAMESPACE
class QPainter;
class QImage;
QT_END_NAMESPACE
class ImageWidget : public QWidget
{
Q_OBJECT
public:
ImageWidget(const QString &filename, QWidget* parent = 0);
~ImageWidget();
bool load(const QString &fileName);
bool save(const QString &fileName);
protected:
void paintEvent(QPaintEvent* event);
private:
QImage img;
};
#endif
imagewidget.cpp
#include <QDebug>
#include "imagewidget.h"
ImageWidget::ImageWidget(const QString &filename, QWidget* parent) : QWidget(parent)
{
img.load(filename);
setMinimumWidth(img.width());
setMinimumHeight(img.height());
setMaximumWidth(img.width());
setMaximumHeight(img.height());
this->show();
}
bool ImageWidget::load(const QString &fileName)
{
img.load(fileName);
return true;
}
bool ImageWidget::save(const QString &fileName)
{
img.save(fileName, "PNG");
return true;
}
ImageWidget::~ImageWidget()
{
}
void ImageWidget::paintEvent(QPaintEvent*)
{
QPainter painter(this);
painter.setViewport(0, 0, width(), height());
painter.setWindow(0, 0, width(), height());
painter.drawImage(0, 0, img);
}
I'm developing a project, and I first began making it without GUI, but now I'm porting it to Qt, but I have a problem.
I have my "old" implementation in a separate file, and I try to access the MainWindow widget from it, in order to output to a QTextBrowser, but I'm not able to do so.
In mainwindow.cpp I have this:
void MainWindow::addString(char* text)
{
std::string input = text;
ui->textBrowser->append(QString::fromStdString(input));
return;
}
In mainwindow.h:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_showWelcome_triggered();
void on_showArithmetic_triggered();
private:
Ui::MainWindow *ui;
public slots:
void btnResolveClicked();
void btnClearClicked();
void hideAll();
void addString(char* output);
};
#endif // MAINWINDOW_H
And in simple_mode.cpp:
void test()
{
MainWindow *gui = new MainWindow;
gui->addString("WORKS");
MainWindow:: = gui;
}
However this doesnt append "WORKS" to the textbrowser, which is what I need, I think it adds it to another instance of text browser which isnt the same as the mainwindow.
EDIT:
What I wanted to do was appending a line of text directly from simple_mode.cpp to the textbrowser.
By the way, simple_mode was written without any Qt aid, that's why I used std strings, and currently the textbrowser widget acts as a virtual terminal output screen, and instead of using printf like I did before, I wanted to append lines to the textbrowser. However I already found my way through, I don't need this now.
I needed help
It's really hard to tell what do you want to achieve and pieces of code do not cover all possible erroneous areas (i.e. where's the MainWindow constructor's definition?). Also, the formatting is terrible - please use idents and consistent bracing style.
My advice is simply call show on MainWindow instance. Unless you don't mess up ui initialization in MainWindow constructor, this snippet should be enough. If it is not - supply us with missing pieces of code.
void test()
{
MainWindow *gui = new MainWindow;
gui->addString("WORKS");
gui->show();
}
As a side note, your addString method should look like this:
void MainWindow::addString(char* text)
{
ui->textBrowser->append(QString::fromAscii(text));
}
Return statement is completely unnecessary, and assigning text to std::string is likely to cause unnecessary memory allocation. It's not like it is the end of the world, but it's really, really bad practice for a C++ programmer.