Qt: Force a repaint to update text from fast button clicks? - c++

I have some very simple code that displays a QPushButton which, when clicked, updates a spinbox with a random number 1 - 100. The problem is I can click the button many times in quick succession and only see one or two updates in the spinbox.
How can I repaint the spinbox for each click on the QPushButton? I've verified that I am firing and catching multiple click signals, but Qt doesn't repaint most of them.
So far I've tried calling repaint(), repaint() on all parent widgets, sendPostedEvents(), and processEvents().
#include <QtWidgets/QWidget>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QSpinBox>
#include <QtWidgets/QLayout>
#include <random>
#include <ctime>
class QtBtnEx : public QWidget
{
Q_OBJECT
public:
QtBtnEx(QWidget *parent = 0);
QPushButton* btn;
QSpinBox* spin;
public slots:
void onClicked();
};
QtBtnEx::QtBtnEx(QWidget *parent)
: QWidget(parent)
{
btn = new QPushButton("button");
spin = new QSpinBox();
btn->setFixedSize(90, 30);
spin->setFixedSize(90, 30);
this->setLayout(new QVBoxLayout());
this->layout()->setAlignment(Qt::AlignCenter);
this->layout()->addWidget(btn);
this->layout()->addWidget(spin);
connect(btn, &QPushButton::clicked, this, &QtBtnEx::onClicked);
}
//Fires for every button click but does not paint for every click
void QtBtnEx::onClicked()
{
srand(time(nullptr));
spin->setValue(rand() % 100);
}

Found my problem; I had the call to srand(time(nullptr)) in the slot code. It was responsible for the delays I was seeing. Pulled it up top and the spinbox refreshes immediately.
#include <QtWidgets/QWidget>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QSpinBox>
#include <QtWidgets/QLayout>
#include <random>
#include <ctime>
class QtBtnEx : public QWidget
{
Q_OBJECT
public:
QtBtnEx(QWidget *parent = 0);
QPushButton* btn;
QSpinBox* spin;
public slots:
void onClicked();
};
QtBtnEx::QtBtnEx(QWidget *parent)
: QWidget(parent)
{
srand(time(nullptr));
btn = new QPushButton("button");
spin = new QSpinBox();
btn->setFixedSize(90, 30);
spin->setFixedSize(90, 30);
this->setLayout(new QVBoxLayout());
this->layout()->setAlignment(Qt::AlignCenter);
this->layout()->addWidget(btn);
this->layout()->addWidget(spin);
connect(btn, &QPushButton::clicked, this, &QtBtnEx::onClicked);
}
void QtBtnEx::onClicked()
{
spin->setValue(rand() % 100);
}

Related

How do I get values from multiple QLineEdit into one matrix?

I'm quite new to QT, and I wanted to do the following:
Have a layout which initially consist of 1 QLineEdit (text) for input and 1 button for confirming it (button).
Then I wanted to send signal SetN(N) when the button is clicked and this signal should activate ArrayEdit(N) slot, which will change the layot to have N inputs (QLineEdit), and 1 button to send what's in them (as one array) to further processing .
I managed to do the first part, but... it didn't work and I don't know how to deal with this no matching member function error
Here's code of my class:
#include "textlayout.h"
TextLayout::TextLayout()
{
setWindowTitle("Choosing N value");
resize(200, 200);
auto layout = new QGridLayout(this);
auto text = new QLineEdit;
text->resize(10, 30);
auto button = new QPushButton();
button->setText("set");
layout->addWidget(text, 0, 0);
layout->addWidget(button, 0, 1);
QObject::connect(&button, SIGNAL(SetN())„ this, SLOT(ArrayEdit())); //no matching member function for call to 'connect'
int N = text->text().toInt();
if(N > 0)
{
emit SetN(N);
}
}
And its header file:
#ifndef TEXTLAYOUT_H
#define TEXTLAYOUT_H
#include <QWidget>
#include <QLineEdit>
#include <QLabel>
#include <QPushButton>
#include <QGridLayout>
#include <QObject>
class TextLayout : public QWidget
{
Q_OBJECT
public:
TextLayout();
public slots:
void ArrayEdit(int N);I
signals:
void SetN(int N);
};
#endif // TEXTLAYOUT_H
I know that actually now I don't activate this signal on click, but... well previously I didn't realize that and I don't know how to have sent parameter with onclick signal...
How can i work around it and how to fix this class?
you are not far away from doing it.. let me help you a little :)
TextLayout::TextLayout()
{
setWindowTitle("Choosing N value");
resize(200, 200);
/*auto*/ layout = new QGridLayout(this);
//declare layout in header, cos you will need it later in the slot
auto text = new QLineEdit;
text->resize(10, 30);
auto button = new QPushButton();
button->setText("set");
layout->addWidget(text, 0, 0);
layout->addWidget(button, 0, 1);
//QObject::connect(&button, SIGNAL(SetN())„ this, SLOT(ArrayEdit())); //no matching member function for call to 'connect'
//you dont need the QObject cos Textlayout is a QObject so just call connect:
connect(this, &TextLayout::SetN, this, &TextLayout::ArrayEdit);
//SetN is not a signal of QButton so you cant connect that like that... instead
connect(&button, &QPushButton::clicked, [this]()
{
int N = text->text().toInt();
if(N > 0)
{
emit SetN(N);
}
});
}
If you handle numeric values use QSpinBox instead of QLineEdit. Then you can also set limits and the user can't input invalid data.
Use QLineEdit for text.
Widget.hpp
#pragma once
#include <QWidget>
class QGridLayout;
class QLineEdit;
class QPushButton;
class QSpinBox;
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void adjustLayout(int n);
private:
QGridLayout* _layout {};
QPushButton* _button {};
QSpinBox* _spinBox {};
QVector<QLineEdit*> _lineEditVector;
};
Widget.cpp
#include "Widget.hpp"
#include <QGridLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QSpinBox>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
_layout = new QGridLayout(this);
_spinBox = new QSpinBox;
_button = new QPushButton("set");
_layout->addWidget(_spinBox, 0, 0);
_layout->addWidget(_button, 0, 1);
connect(_button, &QPushButton::clicked,
this, [this](bool) {
emit adjustLayout(_spinBox->value());
});
}
Widget::~Widget() = default;
void Widget::adjustLayout(int n)
{
for (int i=0; i<n; ++i)
{
QLineEdit* lineEdit = new QLineEdit(QString::number(i+1));
// for later access, keep a reference in the vector:
_lineEditVector.push_back(lineEdit);
_layout->addWidget(lineEdit, i + 1, 0);
}
}

QMenu not execing at correct position first time

I have this very strange issue regarding a QMenu and its position when execing.
Here is the code for my subclassed QMenu:
DockItemContextMenu::DockItemContextMenu(QWidget *parent) : QMenu(parent){
style = qApp->style();
QPointer<QAction> restoreAction = new QAction(QIcon(style->standardIcon(QStyle::SP_TitleBarMaxButton)), "Restore", this);
QPointer<QAction> minimizeAction = new QAction(style->standardIcon(QStyle::SP_TitleBarMinButton), "Minimize", this);
QPointer<QAction> maximizeAction = new QAction(style->standardIcon(QStyle::SP_TitleBarMaxButton), "Maximize", this);
QPointer<QAction> stayOnTopAction = new QAction("Stay On Top", this);
stayOnTopAction->setCheckable(true);
QPointer<QAction> closeAction = new QAction(style->standardIcon(QStyle::SP_TitleBarCloseButton), "Close", this);
this->addActions({restoreAction, minimizeAction, maximizeAction, stayOnTopAction, closeAction});
connect(restoreAction, &QAction::triggered, parent, [this](){ emit restoreTriggered();}, Qt::QueuedConnection);
connect(minimizeAction, &QAction::triggered, parent, [this](){ emit minimizeTriggered();}, Qt::QueuedConnection);
connect(maximizeAction, &QAction::triggered, parent, [this](){ emit maximizeTriggered();}, Qt::QueuedConnection);
connect(stayOnTopAction, &QAction::triggered, parent, [this](){ emit stayOnTopTriggered();}, Qt::QueuedConnection);
connect(closeAction, &QAction::triggered, parent, [this](){ emit closeTriggered();}, Qt::QueuedConnection);
}
Okay, so essentially I have another widget who holds an instance of this DockItemContextMenu as a field. In this owning class, called Titlebar, I made it such that doing a right click will emit the customContextMenuRequested(QPoint) signal.
TitleBar::TitleBar(QString title, QWidget *parent){
...
this->setContextMenuPolicy(Qt::CustomContextMenu);
contextMenu = new DockItemContextMenu(this);
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint)), Qt::QueuedConnection);
...
}
After this, this widget is essentially inserted into a QGraphicsScene and is converted implicitly into a QGraphicsItem. When I do the FIRST right click event on my Titlebar it will not exec at the correct screen position if I dragged the MainWindow of the entire QApplication anywhere other than its starting position on screen. In addition to being in a QGraphicsScene, this scene itself is always stored in a QSplitter. Now I would understand if this always had some sort of issue, but it turns out, every time I call the slot for that signal, ONLY the first time will it exec in the incorrect position in the QGraphicsScene. No matter how I manipulate the size of the Titlebar widget itself, move commands or maximize commands to the MainWindow, or even edit the splitter size for the QGraphicsView that affects the size of the QGraphicsScene, it will always be in the correct position afterwards. here is the function for execing:
void TitleBar::showContextMenu(QPoint point){
qDebug() << point;
contextMenu->exec(point);
emit _parent->focusChangedIn();
}
I printed the point at which it is calling the exec. The strangest part is that both times I right click in the same location, it will print the SAME value for the slot's positional parameter both the first exec and second exec, but be in the correct location every time other than the first. Did I forget to set some other flag when I added the context menu to the Titlebar class? Does it have anything to do with setting the QMenu's parent to the Titlebar? I'm just dumbfounded how the same QPoint could exec at two different screen locations given the same value. Does anybody have a clue what may or may not be happening on the first call to the Titlebar's slot for execing the QMenu?
EDIT: The issue stemmed from doing this line of code in the Titlebar constructor:
contextMenu = new DockItemContextMenu(this);
Changing it to:
contextMenu = new DockItemContextMenu;
fixed the issue. Does anyone know why, or is this possibly a bug? I rather not accept this as an answer because it does not explain why it happened in the first place.
Here is a minimal example with the same effect.
MainWindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QWidget>
#include <QGraphicsView>
#include <QSplitter>
#include <QHBoxLayout>
#include <QGraphicsScene>
#include <QPointer>
#include <QTreeWidget>
#include "titlebar.h"
class MainWindow : public QMainWindow{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
private:
};
#endif // MAINWINDOW_H
MainWindow.cpp:
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
QPointer<QWidget> widgetArea = new QWidget;
QPointer<QHBoxLayout> hLayout = new QHBoxLayout;
widgetArea->setLayout(hLayout);
QPointer<QSplitter> splitter = new QSplitter;
hLayout->addWidget(splitter);
QPointer<QTreeView> tree = new QTreeView;
splitter->addWidget(tree);
QPointer<QGraphicsView> view = new QGraphicsView;
splitter->addWidget(view);
splitter->setStretchFactor(0, 1);
splitter->setStretchFactor(1, 4);
QPointer<QGraphicsScene> scene = new QGraphicsScene;
view->setScene(scene);
QPointer<Titlebar> blue = new Titlebar;
blue->setObjectName("blue");
blue->setStyleSheet(QString("#blue{background-color: rgb(0,0,255)}"));
blue->resize(250,250);
scene->addWidget(blue);
this->setCentralWidget(widgetArea);
this->resize(1000,750);
}
MainWindow::~MainWindow(){
}
Titlebar.h:
#ifndef TITLEBAR_H
#define TITLEBAR_H
#include <QMenu>
#include <QWidget>
#include <QPointer>
#include <QDebug>
#include <QMouseEvent>
class Titlebar : public QWidget{
Q_OBJECT
public:
explicit Titlebar(QWidget *parent = nullptr);
QPointer<QMenu> menu;
QPoint currentPos;
protected slots:
void mousePressEvent(QMouseEvent* event);
void mouseMoveEvent(QMouseEvent* event);
void showContextMenu(QPoint point);
};
#endif // TITLEBAR_H
Titlebar.cpp:
#include "titlebar.h"
Titlebar::Titlebar(QWidget *parent) : QWidget(parent){
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint)), Qt::QueuedConnection);
menu = new QMenu(this);
menu->addAction("Test");
}
void Titlebar::showContextMenu(QPoint point){
qDebug() << point;
menu->exec(mapToGlobal(point));
}
void Titlebar::mouseMoveEvent(QMouseEvent *event){
if (event->buttons() && Qt::LeftButton){
QPoint diff = event->pos() - currentPos;
move(pos() + diff);
}
}
void Titlebar::mousePressEvent(QMouseEvent * event){
currentPos = event->pos();
}
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
So this runs and reproduces the error accordingly. If you change the line in Titlebar.cpp from
menu = new QMenu(this);
to:
menu = new QMenu;
Then it works correctly. ONLY the first right click to open the context menu will spawn in the incorrect location on screen. All subsequent right clicks will now follow either the widget/window/splitter in any combination. I don't get it, can someone tell me if this is actually a bug or not.
You need to add one line of code because your using a QGraphicsProxyWidget which is part of a QGraphicsScene. The scene is represented by a QGraphicsView which inherits QAbstractScrollArea. This causes the context menu to be shown via the viewport and not the widget itself. Therefore adding this one line of code will override the title bar to not be embedded in the scene when it's parent was already embedded in the scene. Effectively making it reference the widget again and not the viewport.
In the MainWindow.cpp right after line 26 add
blue->setWindowFlags(Qt::BypassGraphicsProxyWidget);

Qt Catching signal of checkbox to do an action

In my Qt program, I want to catch the signal of one of my checkbox to know if it's checked or not. I did it :
#include <iostream>
#include <QVBoxLayout>
#include <QtGui>
#include "Window.h"
Window::Window() : QWidget()
{
setFixedSize(400, 800);
m_bouton = new QPushButton("Module 1");
m_bouton->setCursor(Qt::PointingHandCursor);
m_bouton2 = new QPushButton("Module 2");
m_bouton2->setCursor(Qt::PointingHandCursor);
m_bouton3 = new QPushButton("Module 3");
m_bouton3->setCursor(Qt::PointingHandCursor);
m_bouton4 = new QPushButton("Module 4");
m_bouton4->setCursor(Qt::PointingHandCursor);
m_check4 = new QCheckBox(this);
m_check4->move(300, 50);
m_check4->setChecked(true);
m_check3 = new QCheckBox(this);
m_check3->move(200, 50);
m_check3->setChecked(true);
m_check2 = new QCheckBox(this);
m_check2->move(100, 50);
m_check2->setChecked(true);
m_check1 = new QCheckBox(this);
m_check1->move(0, 50);
m_check1->setChecked(true);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(m_bouton);
layout->addWidget(m_bouton2);
layout->addWidget(m_bouton3);
layout->addWidget(m_bouton4);
this->setLayout(layout);
this->setStyleSheet("border: 1px solid black; border-radius: 10px;");
this->setWindowOpacity(0.5);
QWidget::setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
QWidget::setWindowTitle("Monitor Core");
QObject::connect(m_bouton4, SIGNAL(clicked()), this, SLOT(SizeCHange()));
QObject::connect(m_check4, SIGNAL(clicked()), this, SLOT(SizeCHange()));
}
void Window::SizeCHange()
{
setFixedSize(400, 800 - 200);
m_bouton4->setVisible(false);
}
and this is my .h :
#ifndef _WINDOW_H_
#define _WINDOW_H_
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QCheckBox>
class Window : public QWidget
{
Q_OBJECT
public:
Window();
public slots:
void SizeCHange();
private:
QPushButton *m_bouton;
QPushButton *m_bouton2;
QPushButton *m_bouton3;
QPushButton *m_bouton4;
QCheckBox *m_check1;
QCheckBox *m_check2;
QCheckBox *m_check3;
QCheckBox *m_check4;
};
#endif
This is working but just one time. I want to know if it's check or not, then I will be able to resize my window and make something invisible as I want.
You simply need to use a bool parameter, which indicates the state of the checkbox:
public slots:
void SizeCHange(bool checked); //using bool parameter
//...
QObject::connect(m_check4, SIGNAL(clicked(bool)), this, SLOT(SizeCHange(bool)));
//...
void Window::SizeCHange(bool checked)
{
if(checked)
{
setFixedSize(400, 800 - 200);
}
else
{
// removing fixed size
setMinimumSize(QSize(0, 0));
setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
}
m_bouton4->setVisible(checked);
}
The docs for a signal clicked()

Qt QWidget::minimumSizeHint delay

I want to write dialog with "spoiler". When I show/hide some elements, the form must resize to match her content. But I noticed that minimumSizeHint works with some delay. For example I wrote following dialog code:
dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
class Dialog : public QDialog {
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
private:
QPushButton *button1, *button2, *button3;
void adjust();
};
#endif // DIALOG_H
dialog.cpp
#include <QVBoxLayout>
#include <QPushButton>
#include <QTimer>
#include "dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent) {
QVBoxLayout *layout = new QVBoxLayout;
button1 = new QPushButton("bad method", this);
button2 = new QPushButton("working method", this);
button3 = new QPushButton("indent", this);
layout->addWidget(button1);
layout->addWidget(button2);
layout->addWidget(button3);
setLayout(layout);
connect(button1, &QPushButton::pressed, [=]() {
button3->setVisible(!button3->isVisible());
adjust();
});
connect(button2, &QPushButton::pressed, [=]() {
button3->setVisible(!button3->isVisible());
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, [=](){ adjust(); });
timer->setSingleShot(true);
timer->start(0);
});
}
void Dialog::adjust() {
resize(width(), minimumSizeHint().height());
}
When pressed button1, the form isn't match her content tightly, but when pressed button2, the form tightly match her content.
How to achieve results as pressing button2 without timers and other workarounds? Why button1 isn't work?
Consider that the minimum size is not computed until some events are processed in the event loop. If you don't want to use a timer, one workaround is to process the event loop for some iterations after the button is hidden or made visible, and then adjust size.
It's like :
button3->setVisible(!button3->isVisible());
for(int i=0;i<10;i++)
qApp->processEvents();
adjust();
A better solution is to call QLayout::activate() before resizing:
button3->setVisible(!button3->isVisible());
layout->activate();
adjust();
activate() forces your layout to recalculate the size hint.
I tried the QLayout::activate() solution, but it doesn't work for me.
QLayout::activate() returns false.
This is my code: this is a QMainWindow.
ui.groupBox->setVisible(!ui.groupBox->isVisible());
qDebug() << this->layout()->activate();
qDebug() << this->minimumSizeHint();
this->resize(this->minimumSizeHint());
any ideas why it's not working?
My current workaround is:
QTimer::singleShot(10, this, SLOT(on_resizeMin()));
but i noticed 10ms may not be enough on a slow system. Nasty workaround.

QPushButton gets stuck drawing pressed when transfer of focus to button is interrupted

I have some forms with input fields that provide warnings to the user when the fields looses focus (if something is wrong of course). To that end I’ve created my own control that inherits from QLineEdit. For this question consider the extremely simple field that will pop a message box whenever focus is lost when there is text in the control. The actual controls have more logic but all are supposed to pop a message box. (Crossposted to qtcentre.org)
class test_line_edit : public QLineEdit
{
Q_OBJECT
public:
test_line_edit(QWidget * parent = 0) : QLineEdit(parent)
{}
~test_line_edit(){}
protected:
virtual void focusOutEvent(QFocusEvent * e)
{
if(!text().isEmpty())
{
QMessageBox msg;
msg.setText(tr("Test"));
msg.exec();
setFocus(Qt::OtherFocusReason);
}
else
{
QLineEdit::focusOutEvent(e);
}
}
};
Now say I have a simple form with just one of these controls and a QPushButton. If the user types in the control and then clicks the button the messagebox pops but the button gets stuck being drawn looking like it’s pressed. How can I make that stop? As best I can tell the QPushButton’s pressed signal is getting fired but that is all I can hear from the button. Since these test_line_edit controls are going to be used everywhere on many different forms I’m hoping there is something I can change inside the test_line_edit class that will fix the problem. Running Qt 4.7.0 on Windows XP using Visual Studio 2010.
I’ve seen this bug and not sure if it’s related since it’s a different platform and I’m not actually holding the button down: http://bugreports.qt-project.org/browse/QTBUG-7901
Here’s a full program that demonstrates the problem (warning: some code generated from the Qt VS plugin)
main.h:
#include <QtGui/QMainWindow>
#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QHeaderView>
#include <QtGui/QMainWindow>
#include <QtGui/QMenuBar>
#include <QtGui/QPushButton>
#include <QtGui/QStatusBar>
#include <QtGui/QToolBar>
#include <QtGui/QVBoxLayout>
#include <QtGui/QWidget>
#include <QLineEdit>
#include <QMessageBox>
class test_line_edit : public QLineEdit
{
Q_OBJECT
public:
test_line_edit(QWidget * parent = 0) : QLineEdit(parent)
{}
~test_line_edit(){}
protected:
virtual void focusOutEvent(QFocusEvent * e)
{
if(!text().isEmpty())
{
QMessageBox msg;
msg.setText(tr("Test"));
msg.exec();
//setFocus(Qt::OtherFocusReason);
}
else
{
QLineEdit::focusOutEvent(e);
}
QLineEdit::focusOutEvent(e);
}
};
QT_BEGIN_NAMESPACE
class Ui_btn_drawing_testClass
{
public:
QWidget *centralWidget;
QVBoxLayout *verticalLayout;
test_line_edit *line_edit;
QPushButton *btn;
QMenuBar *menuBar;
QToolBar *mainToolBar;
QStatusBar *statusBar;
void setupUi(QMainWindow *btn_drawing_testClass)
{
if (btn_drawing_testClass->objectName().isEmpty())
btn_drawing_testClass->setObjectName(QString::fromUtf8("btn_drawing_testClass"));
btn_drawing_testClass->resize(167, 127);
centralWidget = new QWidget(btn_drawing_testClass);
centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
verticalLayout = new QVBoxLayout(centralWidget);
verticalLayout->setSpacing(6);
verticalLayout->setContentsMargins(11, 11, 11, 11);
verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
line_edit = new test_line_edit(centralWidget);
line_edit->setObjectName(QString::fromUtf8("line_edit"));
verticalLayout->addWidget(line_edit);
btn = new QPushButton(centralWidget);
btn->setObjectName(QString::fromUtf8("btn"));
verticalLayout->addWidget(btn);
btn_drawing_testClass->setCentralWidget(centralWidget);
menuBar = new QMenuBar(btn_drawing_testClass);
menuBar->setObjectName(QString::fromUtf8("menuBar"));
menuBar->setGeometry(QRect(0, 0, 167, 20));
btn_drawing_testClass->setMenuBar(menuBar);
mainToolBar = new QToolBar(btn_drawing_testClass);
mainToolBar->setObjectName(QString::fromUtf8("mainToolBar"));
btn_drawing_testClass->addToolBar(Qt::TopToolBarArea, mainToolBar);
statusBar = new QStatusBar(btn_drawing_testClass);
statusBar->setObjectName(QString::fromUtf8("statusBar"));
btn_drawing_testClass->setStatusBar(statusBar);
retranslateUi(btn_drawing_testClass);
QMetaObject::connectSlotsByName(btn_drawing_testClass);
} // setupUi
void retranslateUi(QMainWindow *btn_drawing_testClass)
{
btn_drawing_testClass->setWindowTitle(QApplication::translate("btn_drawing_testClass", "btn_drawing_test", 0, QApplication::UnicodeUTF8));
btn->setText(QApplication::translate("btn_drawing_testClass", "PushButton", 0, QApplication::UnicodeUTF8));
} // retranslateUi
};
namespace Ui {
class btn_drawing_testClass: public Ui_btn_drawing_testClass {};
} // namespace Ui
QT_END_NAMESPACE
class btn_drawing_test : public QMainWindow
{
Q_OBJECT
public:
btn_drawing_test(QWidget *parent = 0, Qt::WFlags flags = 0): QMainWindow(parent, flags)
{
ui.setupUi(this);
}
~btn_drawing_test(){}
private:
Ui::btn_drawing_testClass ui;
protected slots:
void on_btn_clicked()
{
int breakpoint = 5;
}
void on_btn_pressed()
{
int breakpoint = 5;
}
void on_btn_toggled(bool)
{
int breakpoint = 5;
}
};
main.cpp:
#include <QtGui/QApplication>
#include "main.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
btn_drawing_test w;
w.show();
return a.exec();
}
Thank you for your help and please let me know if I can provide any more information.
I've made some changes to your line edit class, see if it solves the problem:
class test_line_edit : public QLineEdit
{
Q_OBJECT
public:
test_line_edit(QWidget * parent = 0) : QLineEdit(parent) {}
~test_line_edit(){}
protected:
virtual void focusOutEvent(QFocusEvent * e)
{
QLineEdit::focusOutEvent(e);
QEvent *event = new QEvent(QEvent::User);
QApplication::postEvent(this, event);
}
virtual void customEvent(QEvent * event)
{
QLineEdit::customEvent(event);
if (event->type()==QEvent::User)
{
QMessageBox msg;
msg.setText(tr("Test"));
msg.exec();
setFocus(Qt::OtherFocusReason);
}
}
};
Instead of showing modal window in the focusOutEvent method, I've posted an event into the event queue. This worked fine on my ubuntu, don't expect any problems on windows either.
hope this helps, regards