How to make latency of QPushButton for push? - qt

I would like to create QPushButton which gives an opportunity to press not often than one time in 200 msec. When I use func sleep(200) all GUI thread will stop.
Waiting for your ideas!
Thankx!

Something like this:
class Controller : public QObject
{
// ...
private:
QPointer< QPushButton > btn;
private slots:
void onClicked();
void enableClick();
};
Controller::onClicked()
{
disconnect( btn, SIGNAL( clicked() ), SLOT( onClicked() ) );
QTimer::singleShot( 200, this, SLOT( enableClick() ) );
// Optional
btn->setEnabled( false );
}
Controller::enableClick()
{
connect( btn, SIGNAL( clicked() ), SLOT( onClicked() ) );
// Optional
btn->setEnabled( true );
}

Related

How to add 2 custom buttons for QLineEdit?

I tried to add two buttons for my line edit. The "clear" appears only when the text in line edit not empty, and the "bulb" is always shown.
MyLineEdit.cpp
MyLineEdit::MyLineEdit( QWidget *p_parent ) : QLineEdit( p_parent )
{
m_buttonAction = addAction( QIcon( ":/bulb" ), QLineEdit::TrailingPosition );
QToolButton *button = dynamic_cast<QToolButton *>( m_buttonAction->associatedWidgets().at( 1 ) );
button->setCursor( QCursor( Qt::PointingHandCursor ) );
m_buttonAction->setVisible( true );
m_clearAction = addAction( QIcon( ":/clear" ), QLineEdit::TrailingPosition );
QToolButton *clear = dynamic_cast<QToolButton *>( m_clearAction->associatedWidgets().at( 1 ) );
clear->setCursor( QCursor( Qt::PointingHandCursor ) );
m_clearAction->setVisible( false );
connect( this, &MyLineEdit::textChanged, this, &MyLineEdit::toggleClearButton );
connect( m_clearAction, &QAction::triggered, this, &QLineEdit::clear );
connect(m_buttonAction, &QAction::triggered, this, &MyLineEdit::doSomething);
}
void MyLineEdit::toggleClearButton()
{
text().isEmpty() ? m_clearAction->setVisible( false ) : m_clearAction->setVisible( true );
}
void MyLineEdit::doSomething()
{
}
MyLineEdit.h
class MyLineEdit : public QLineEdit
{
Q_OBJECT
public:
MyLineEdit( QWidget *p_parent = nullptr );
private slots:
void toggleClearButton();
void doSomething();
private:
QAction *m_clearAction = nullptr;
QAction *m_buttonAction = nullptr;
};
When I run the program, the "bulb" does not appear at the beginning
Only when I type something in the line edit, the "bulb" is then shown as I want
Why is the "bulb" not shown at the beginning, where do I have error here?

Avoid QTimer to emit timeout signal

I have started Timer to wait for certain condition to be true. IF condition is true then I stop timer and dont want timeout signal to emit or execute connnected slot. But if condition is false within specified time then its allright to emit signal timeout(). But whatever is the case it always emit timeout signal. I have used blockSignals ( true ) as well and it doesnt work. Can some one please advice me.
void timerStart( QTimer* timer, int timeMillisecond )
{
timer = new QTimer( this );
timer->setInterval( timeMillisecond );
timer->setSingleShot( true );
connect( timer, SIGNAL( timeout() ), this, SLOT( noRespFrmServer( ) ) ) ;
//timer->start( timeMillisecond );
timer->start();
}
void timerStop( QTimer* timer )
{
connect( timer, SIGNAL( destroyed( timer ) ), this, SLOT( stopTimerbeforeTimeout( ) ) );
qDebug() << " we are in timer stop";
if( timer )
{
timer->stop();
timer->blockSignals( true );
delete timer;
}
}
Also in timerStop function I have tried to emit destroyed signal but I got response that it fails to connect.
pLease advice me.
void timerStart( QTimer* timer, int timeMillisecond )
{
timer = new QTimer( this );
timer->setInterval( timeMillisecond );
timer->setSingleShot( true );
connect( timer, SIGNAL( timeout() ), this, SLOT( noRespFrmServer( ) ) ) ;
//timer->start( timeMillisecond );
timer->start();
}
This doesn't actually return the timer you just created. You want something like:
QTimer *timerStart(int timeMillisecond )
{
QTimer* timer = new QTimer( this );
timer->setInterval( timeMillisecond );
timer->setSingleShot( true );
connect( timer, SIGNAL( timeout() ), this, SLOT( noRespFrmServer( ) ) ) ;
//timer->start( timeMillisecond );
timer->start();
return timer;
}
Then you can pass the returned timer into the stop function though I suggest you use deleteLater instead of straight up deleting it:
void timerStop( QTimer* timer )
{
qDebug() << " we are in timer stop";
if( timer )
{
qDebug() << " we are stopping the timer";
timer->stop();
timer->blockSignals( true );
timer->deleteLater();
}
}

Connecting QWidget to slot QStackedWidget::setCurrentWidget

I'm attempting to toggle stacked push buttons as show in the following application.
Declaration:
#include <QPushButton>
#include <QMainWindow>
#include <QStackedWidget>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
private:
QPushButton* m_button[2];
QStackedWidget *m_buttonStack;
};
Implementation (take note of the connects):
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
resize(300, 300);
m_buttonStack = new QStackedWidget( this );
m_buttonStack->setGeometry( 100, 100 , 100 , 100 );
m_button[0] = new QPushButton( this );
m_button[0]->setText( "Button 1" );
m_buttonStack->addWidget( m_button[0] );
m_button[1] = new QPushButton( this );
m_button[1]->setText( "Button 2" );
m_buttonStack->addWidget( m_button[1] );
m_buttonStack->setCurrentWidget( m_button[1] );
QObject::connect( m_button[0] , SIGNAL( clicked() ) , m_buttonStack , SLOT( setCurrentWidget( m_button[1] ) ) );
QObject::connect( m_button[1] , SIGNAL( clicked() ) , m_buttonStack , SLOT( setCurrentWidget( m_button[0] ) ) );
}
For some inexplicable reason, although QStackedWidget::setCurrentWidget is defined QObject::connect is unable to connect to it, as the following error messages, copied from the application output window, show:
Object::connect: No such slot QStackedWidget::setCurrentWidget( m_button[1] ) in ..\mainwindow.cpp:21
Object::connect: No such slot QStackedWidget::setCurrentWidget( m_button[0] ) in ..\mainwindow.cpp:22
you'll want to use a QSignalMapper
connect(m_button[0], SIGNAL(clicked()), m_signalMapper, SLOT(map()));
m_signalMapper->setMapping(m_button[0],m_button[1]);
connect(m_button[1], SIGNAL(clicked()), m_signalMapper, SLOT(map()));
m_signalMapper->setMapping(m_button[1],m_button[0]);
QObject::connect(signalMapper , SIGNAL( mapped(QWidget *) ) , m_buttonStack , SLOT( setCurrentWidget(QWidget *) ) );
You don't need to provide the actual argument(s) when refer to the function signature in the SLOT macro:
QObject::connect( m_button[0], SIGNAL( clicked() ), m_buttonStack, SLOT( setCurrentWidget( m_button[1] ) ) );
Should be something like this:
QObject::connect( m_button[0], SIGNAL( clicked() ), m_buttonStack, SLOT( setCurrentWidget( QWidget *) ) );
As you could see, even in this way, the connection will not work. I suggest to implement your own slot (without arguments) and connect your buttons clicks to it:
QObject::connect(m_button[0], SIGNAL(clicked()), this, SLOT(onButtonClicked()));
than, in the slot, you can handle the click:
void MainWindow::onButtonClicked()
{
// Get the button clicked
QPushButton *btn = qobject_cast<QPushButton *>(sender());
m_buttonStack->setCurrentWidget(btn);
}
Thus you can even remove your buttons array.

clicked() signal in a button

I've got some problem with signal for a button in Qt 4.8.0. I am using vs 2010 with Qt Designer. I have created a button in Designer with playButton name. But after that I tried to connect clicked() signal (in vs) with my function from CRenderArea (to start a timer), but it seems that it doesn't work (the function start() works when I put it in the constructor, so it's not the problem of the code itself). The code is compiling, the program is executing, but after clicking a button - nothing happens (it should move a line).
I would be really thankful for some help, just started a fun with Qt.
The codes are here (I hope the number of files won't scare you, these are the simplest codes ever :) ):
main.cpp
#include "ts_simulator.h"
#include <QtGui/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
TS_simulator w;
w.show();
return a.exec();
}
ts_simulator.cpp:
TS_simulator::TS_simulator(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
p_map = new CRenderArea();
ui.setupUi( this );
p_map->setParent( ui.renderArea );
// this doesn't work, why?
connect( ui.playButton, SIGNAL( clicked() ), this, SLOT( p_map->start() ) );
}
CRenderArea.h
#pragma once
#include <QtGui>
class CRenderArea : public QWidget {
Q_OBJECT // I think it's necessary?
int x;
QBasicTimer* timer;
public:
CRenderArea();
public slots: // this is necessary too, right?
void start();
private:
void timerEvent( QTimerEvent* );
void paintEvent( QPaintEvent* );
};
and CRenderArea.cpp:
#include "CRenderArea.h"
CRenderArea::CRenderArea() : x( 0 ) {
setBackgroundRole( QPalette::Base );
setMinimumSize( 591, 561 );
setAutoFillBackground( true );
timer = new QBasicTimer();
}
void CRenderArea::timerEvent( QTimerEvent* e ) {
++x;
update();
}
void CRenderArea::paintEvent( QPaintEvent* p ) {
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(Qt::darkGray);
painter.drawLine(2+x/10, 8, 60, 300);
}
void CRenderArea::start() {
timer->start( 0, this );
}
Greets.
The problem is here:
connect( ui.playButton, SIGNAL( clicked() ), this, SLOT( p_map->start() ) );
if p_map is the receiver of the signal, and it has Q_OBJECT, it should be written as:
connect( ui.playButton, SIGNAL( clicked() ), p_map, SLOT(start()) );

QPainter and QTimer

How to use QPainter and QTimer to draw a real time sinusoid like
sinus( 2 * w * t + phi )
thanks.
I would assume something like this, for the interaction between QTimer and painting:
// Periodically paints a sinusoid on itself.
class SinPainter : public QWidget
{
Q_OBJECT
public:
SinPainter( QWidget *parent_p = NULL ) :
QWidget( parent_p ),
m_timer_p( new QTimer( this ) ),
m_t( 0.0 )
{
// When the timer goes off, run our function to change the t value.
connect( m_timer_p, SIGNAL( timeout() ), SLOT( ChangeT() ) );
// Start the timer to go off every TIMER_INTERVAL milliseconds
m_timer_p->start( TIMER_INTERVAL );
}
// ...
protected slots:
void ChangeT()
{
// Change m_t to the new value.
m_t += T_INCREMENT;
// Calling update schedules a repaint event, assuming one hasn't
// already been scheduled.
update();
}
protected:
void paintEvent( QPaintEvent *e_p )
{
QPainter painter( this );
// Use painter and m_t to draw your current sinusoid according
// to your function.
}
private:
QTimer *m_timer_p;
double m_t; // <-- Or whatever variable type it needs to be.
};

Resources