I'm doing the Udemy C++ Qt tutorial. The idea is to have a QPushButton button in a window.
When I run this, I get an empty window. Using Qt 5.5 in Win7.
Here are my files:
main.cpp
#include<QApplication>
#include"S_S.h"
int main(int argc, char *argv[])
{
QApplication app(argc,argv);
S_S MyTest;
MyTest.show();
return app.exec();
}
S_S.h
#ifndef S_S_H
#define S_S_H
#include<QApplication>
#include<QWidget>
#include<QPushButton>
class S_S : public QWidget
{
public:
S_S();
private:
QPushButton *Button1;
};
#endif // S_S_H
S_S.cpp
#include"s_s.h"
S_S::S_S():QWidget()
{
Button1=new QPushButton;
Button1->setText("Cancel");
connect(Button1,SIGNAL(clicked()),qApp,SLOT(quit()));
}
You probably want to construct the QPushButton and pass in a parent widget:
Button1 = new QPushButton(this);
I assume you want the S_S instance to be the parent.
You might also want to set the size and location of the button:
Button1->setGeometry(QRect(QPoint(100, 100), QSize(200, 50)));
There is an example here of using QPushButton.
Related
In a widget I put two QPushButton (let's say "OK" at left and "EXIT" at right).
They regularly work when I press them using the mouse.
Suppose I want to switch from one to the other using TAB key: is it possible?
And how can do this?
On some platforms, keyboard focus navigation among buttons is a default behavior, but on some it isn't.
If you wish keyboard navigation on all platforms, the buttons should have a Qt::StrongFocus policy set on them. Note that the shortcut used to trigger the buttons is also platform-specific. E.g. on OS X you'd use Space.
#include <QtWidgets>
int main(int argc, char ** argv) {
QApplication app{argc, argv};
QWidget w;
QVBoxLayout layout{&w};
// Individual Buttons
QPushButton p1{"button1"}, p2{"button2"};
for (auto p : {&p1, &p2}) {
layout.addWidget(p);
p->setFocusPolicy(Qt::StrongFocus);
}
// A button box
QDialogButtonBox box;
for (auto text : {"button3", "button4"})
box.addButton(text, QDialogButtonBox::NoRole)->setFocusPolicy(Qt::StrongFocus);
layout.addWidget(&box);
w.show();
return app.exec();
}
I tried it out on KDE/Ubuntu. It works automatically.
main.cpp
#include <QApplication>
#include "mainwindow.hpp"
int main(int argc, char** args) {
QApplication app(argc, args);
MainWindow m;
m.show();
return app.exec();
}
mainwindow.hpp
#ifndef MAINWINDOW_HPP
#define MAINWINDOW_HPP
#include <QMainWindow>
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow();
};
#endif // MAINWINDOW_HPP
mainwindow.cpp
#include "mainwindow.hpp"
#include <QPushButton>
#include <QVBoxLayout>
MainWindow::MainWindow() : QMainWindow() {
auto* w = new QWidget;
auto* l = new QVBoxLayout;
auto* p1 = new QPushButton("ok");
auto* p2 = new QPushButton("exit");
l->addWidget(p1);
l->addWidget(p2);
w->setLayout(l);
setCentralWidget(w);
}
a.pro
TEMPLATE = app
TARGET = a
INCLUDEPATH += .
QT += widgets
HEADERS += mainwindow.hpp
SOURCES += main.cpp mainwindow.cpp
QMAKE_CXXFLAGS += -std=c++14
Edit: Apparently the buttons switch focus, but pressing enter does nothing. I guess you have to use focus-related mechanics (search for "focus" in the QWidget documentation) and implement it yourself. Or have a look at QDialog (as a replacement for QMainWindow in my example). It should have some meaningful default behavior for the enter and escape buttons.
Side note: Maybe you rather want to use the QDialogButtonBox for ok- and exit-buttons in your project. It's the cross-platform way of displaying OK/Cancel/Accept/Reject/... buttons because their arrangement differs between platforms. And this class can help you with that.
It is easier than all that code. Just use setFocusPolicy with Tabfocus on both buttons like this:
yourButtonOk->setFocusPolicy(Qt::TabFocus);
yourButtonExit->setFocusPolicy(Qt::TabFocus);
I have a WidgetA widget, which is an owner-drawn widget. It's currently placed in QMainWindow's QVBoxLayout. After clicking a button, I'd like to "detach" WidgetA from this QVBoxLayout, insert QSplitter into this QVBoxLayout and "readd" WidgetA to this QSplitter. All this without destroying WidgetA, so it will preserve its drawing context, etc.
So, currently I have this (only one widget in a window):
I'd like to put a QSplitter between WidgetA and QMainWindow, and create a new widget, WidgetB, so I'd end up with:
Later I'd like it to split even further, so both WidgetA and WidgetB would still allow themselves to be detached and placed in a new QSplitter, so it would be possible to create f.e. this hierarchy:
And, to be complete, one more step:
I'm not very experienced in Qt, so what I'm trying to do may seem pretty obvious, but I couldn't find how to "reparent" widgets. Is this possible in Qt?
Please, see reparent example, may be it helps you:
//MyMainWindow.h
#include <QWidget>
#include <QPainter>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QSplitter>
class MyWidget: public QWidget
{
public:
MyWidget(QWidget* parent, int number)
: QWidget(parent),
m_number(number)
{
}
private:
virtual void paintEvent(QPaintEvent* e)
{
QWidget::paintEvent(e);
QPainter p(this);
p.fillRect( rect(), Qt::red);
p.drawText( rect(), Qt::AlignCenter, QString::number(m_number) );
}
private:
int m_number;
};
class MyMainWindow: public QWidget
{
Q_OBJECT
public:
MyMainWindow()
{
setFixedSize(300, 200);
m_mainLayout = new QVBoxLayout(this);
QHBoxLayout* buttonLayout = new QHBoxLayout;
m_mainLayout->addLayout(buttonLayout);
m_button = new QPushButton("Button", this);
buttonLayout->addWidget(m_button);
connect(m_button, SIGNAL(clicked()), this, SLOT(onButtonClickedOnce()));
m_initWidget = new MyWidget(this, 1);
m_mainLayout->addWidget(m_initWidget);
}
private slots:
void onButtonClickedOnce()
{
m_button->disconnect(this);
m_mainLayout->removeWidget(m_initWidget);
QSplitter* splitter = new QSplitter(Qt::Horizontal, this);
m_mainLayout->addWidget(splitter);
splitter->addWidget(m_initWidget);
MyWidget* newWidget = new MyWidget(splitter, 2);
splitter->addWidget(newWidget);
}
private:
QVBoxLayout* m_mainLayout;
QWidget* m_initWidget;
QPushButton* m_button;
};
//main.cpp
#include <QtWidgets/QApplication>
#include "MyMainWindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyMainWindow mainWindow;
mainWindow.show();
return a.exec();
}
When you operate with widget which is part of layout, then you need to use appropriate methods of QLayout (parent of QVBoxLayout) to detach the item from layout:
QLayout::removeWidget (removeItem if it is not widget, but spacer item or another layout)
QLayout::addWidget (addItem --/--)
Btw: even when widget moves between layouts, its parent may even stay same. I guess you have no need to call QWidget::setParent() as the calls of addWidget/removeWidget will do all work for you.
I am a newbie in Qt-programming. I have read a book about GUI-programming with Qt. I have an trouble in creating a dialog. Here is sample code:
// gotocell.h
#ifndef GOTOCELL_H
#define GOTOCELL_H
#include <QDialog>
#include <QtWidgets>
#include "ui_gotocell.h"
class GoToCellDialog : public QDialog, public Ui::GoToCellDialog
{
Q_OBJECT
public:
GoToCellDialog (QWidget *parent = 0);
private slots:
void on_lineEdit_textChanged();
};
#endif // GOTOCELL_H
// gotocell.cpp
#include <QtWidgets>
#include "gotocell.h"
#include <QtWidgets>
GoToCellDialog::GoToCellDialog (QWidget *parent):
QDialog (parent)
{
setupUi(this);
QRegExp regExp ("[A-Za-z][1-9][0-9]{0,2}");
lineEdit->setValidator(new QRegExpValidator(regExp, this));
connect (okButton, SIGNAL(clicked()), this, SLOT(accept()));
connect (cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
}
void GoToCellDialog::on_lineEdit_textChanged()
{
okButton->setEnabled(lineEdit->hasAcceptableInput());
}
// main.cpp
#include "gotocell.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
GoToCellDialog *dialog = new GoToCellDialog;
dialog->show();
return a.exec();
}
but when I compiled, there is an error: no known conversion for argument 1 from 'GoToCellDialog* const' to 'QMainWindow*'at setupUi() function. I think because the designer in Qt Creator created a QMainWindow, not a QDialog. So I changed GoToCellDialog class to QMainWindow. But there is no slots whose name is "accepted", "rejected" in QMainWindow. Can anyone help me?
If you want to display a Dialog as main window you have two choices:
1. make the whole main window QDialog based
2. design the Dialog separately and set it as the main windows central Widget (QMainWindow->setCentralWidget()).
In both cases you still have the problem what semantics you give to the OK and Cancel buttons. Generally it may be a better idea to consider what the main window of the application should contain, and design the dialogs later.
I want to make the background of a QDialog transparent so that I can see through the window. I'm asking because I want to use a semi-transparent background image that creates a "rounded corner window" illusion. Using setOpacity is not an option for me because I want all widgets to remain at full opacity.
Is there a way to achieve this without resorting to native OS APIs?
Use QWidget::setAttribute(Qt::WA_TranslucentBackground);. Note that this also requires Qt::FramelessWindowHint to be set.
This example works for me:
#include <QtGui>
class Dialog : public QDialog
{
public:
Dialog() : QDialog(0, Qt::FramelessWindowHint) // hint is required on Windows
{
QPushButton *button = new QPushButton("Some Button", this);
setAttribute(Qt::WA_TranslucentBackground);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog d;
d.show();
return a.exec();
}
Regarding rounded corners, QWidget::setMask() will help you.
EDIT: In response to another question below in the comments, here is a working example that uses an image in a resources file, and that overrides QWidget::paintEvent():
#include <QtGui>
class Dialog : public QDialog
{
public:
Dialog() : QDialog(0, Qt::FramelessWindowHint) // hint is required on Windows
{
setFixedSize(500, 500); // size of the background image
QPushButton *button = new QPushButton("Some Button", this);
setAttribute(Qt::WA_TranslucentBackground);
}
protected:
void paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.drawImage(QRectF(0, 0, 500, 500), QImage(":/resources/image.png"));
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog d;
d.show();
return a.exec();
}
How i can add QRadioButtons in a QFrame on runtime?
Thanks.
Add the widget to the appropriate place by calling the addWidget() method, such as:
ui->someLayout->addWidget(widgetToAdd);
Just make sure you do this in your main (UI) thread.
you can add a QRadioButtons on runtime normally in the same way you do before runtime.
you create the QRadioButton dynamically and call the addWidget method of QFrame layout.
if you are not ableto do it, post the code and let me show you.
mainwindow.h
#include <QtGui/QMainWindow>
#include <QPushButton>
#include <QHBoxLayout>
#include <QRadioButton>
class MainWindow : public QMainWindow
{
Q_OBJECT
QHBoxLayout * layout;
QPushButton * button;
public:
MainWindow(QWidget *parent = 0);
public slots:
void radioAdd();
};
mainwindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
layout = new QHBoxLayout(this);
QWidget * w = new QWidget(this);
w->setLayout(layout);
this->setCentralWidget(w);
button = new QPushButton(QString("push"),this);
layout->addWidget(button);
connect(button,SIGNAL(clicked()), this, SLOT(radioAdd()));
}
void MainWindow::radioAdd() {
QRadioButton * radio = new QRadioButton("Search from the &cursor", this);
layout->addWidget(radio);
}
main.cpp
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
in this code the radioButton get created in the runtime (in the slot function radioAdd). and in your case, instead of adding QRadioButton into the wigdet layout you add them into QFrame.