Qt: get text from button in QTableWidget - c++

I have QTableWidget in my Qt application, and I add buttons to it like that:
QPushButton *startButton = new QPushButton("start");
ui->tableWidget_tvConnection->setCellWidget(row, col, startButton);
connect(startButton, SIGNAL(clicked()), this, SLOT(startButtonPressed()));
And when it is pressed I need to get text from it, so I tried this:
void MainWindow::startButtonPressed()
{
...
QPushButton *button = ui->tableWidget_tvConnection->cellWidget(row, col);
qDebug() << button->text();
}
But compiler doesn't allow me to convert from QWidget* to QPushButton*:
error: invalid conversion from 'QWidget*' to 'QPushButton*' [-fpermissive]
So Is it even possible to get text from button inside QTableWidget?
If it isn't I have another way how to handle this in my application, but this would be really nice.

You get QWidget, so you should cast it to QPushButton. After that, you will be able to use this as a normal pushbutton. Try this:
QPushButton *button = qobject_cast<QPushButton *>(ui->tableWidget_tvConnection->cellWidget(row, col));
if(button) {
//success
} else {
//bad
}

Related

How to programmatically change style sheet of buttons in Qt?

I have so many buttons on a dialog and I want to change style sheets of them under some conditions.
Button object names are like below:
btn_1
btn_2
btn_3
..
btn_20
When I clicked one of these numerical buttons and later to another simple button, I want to change first clicked numerical button style sheet. How can I access that selected numerical button?
Edit:
What I mean by picture
I am trying to set colors of left column buttons (has numerically ordered object names) with right column buttons. User will be clicked numerical buttons first and then color named buttons.
You have to use the setStyleSheet method but you have to keep the reference of the button pressed, and that can be done using the sender method that returns the object that emitted the signal.
#include <QtWidgets>
class MainWindow: public QMainWindow{
Q_OBJECT
public:
MainWindow(QWidget *parent=nullptr):
QMainWindow(parent),
current_button(nullptr)
{
QWidget *widget = new QWidget;
setCentralWidget(widget);
QHBoxLayout *hlay = new QHBoxLayout(widget);
QVBoxLayout *number_lay = new QVBoxLayout;
QVBoxLayout *color_lay = new QVBoxLayout;
hlay->addLayout(number_lay);
hlay->addLayout(color_lay);
for(int i=0; i<20; i++){
QPushButton *button = new QPushButton(QString("btn_%1").arg(i+1));
connect(button, &QPushButton::clicked, this, &MainWindow::number_clicked);
number_lay->addWidget(button);
}
color_lay->addStretch();
for(const QString & colorname: {"Red", "Green", "Blue"}){
QPushButton *button = new QPushButton(colorname);
connect(button, &QPushButton::clicked, this, &MainWindow::color_clicked);
color_lay->addWidget(button);
button->setProperty("color", colorname.toLower());
button->setStyleSheet(QString("background-color: %1").arg(colorname));
}
color_lay->addStretch();
}
private slots:
void number_clicked(){
current_button = qobject_cast<QPushButton *>(sender());
}
void color_clicked(){
if(current_button){
QString colorname = sender()->property("color").toString();
current_button->setStyleSheet(QString("background-color: %1").arg(colorname));
}
}
private:
QPushButton *current_button;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#include "main.moc"
When you click on the first button, get its name using the method objectName(), then when you need to change the style, just specify in the method
setStyleSheet(QString(QPushButton#) + button->objectName() + QString("{ ... }");
I can write the example-program, but I do not fully understand what you want

QTableWidget selection rectangle does not disappear even after editing is finished

I am implementing a QTableWidget, the selection rectangle seems not to be disappearing even after I finish editing and change my selection to other cells.
Below is a screenshot of the QTableWidget.
Below is the code for constructing the tablewidget, rows are added dynamically via a QPushButton:
{
setObjectName(obj_name);
layout = new QVBoxLayout();
table = new QTableWidget(this);
table->verticalHeader()->setVisible(false);
table->verticalHeader()->setDefaultSectionSize(20);
table->setFixedWidth(180);
table->setColumnCount(3);
table->setColumnWidth(0,75);
table->setColumnWidth(1, 75);
table->setColumnWidth(2, 25);
QStringList header = { "Tag", "Threshold" ,""};
table->setHorizontalHeaderLabels(header);
table->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
add = new QPushButton("+", this);
add->setObjectName("btn_threshold_add");
layout->addWidget(table);
layout->addWidget(add);
setLayout(layout);
connect(add, SIGNAL(clicked()), this, SLOT(add_row()));
}
Below is the code for add_row() SLOT, triggers when user clicked the add button:
void TagThresholdWidget::add_row()
{
int row = table->rowCount();
QPushButton *del = new QPushButton("-", table);
table->insertRow(row);
table->setCellWidget(row, 2, del);
connect(del, SIGNAL(clicked()), this, SLOT(remove_row()));
}
Anyone has any clue to how to solve this problem? Its seems like a Qt graphical paint bug to me

Qt: How to set "?" button for a QWidget?

In a QWidget like QLabel, how can we set a "?" button, such that when clicked (or hovered) it should show some help text.
Also you can use QMenu instead of QPushButton + QLabel.
// Constructor
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotCustomMenu(QPoint)));
// slotCustomMenu(QPoint)
QMenu menu(this);
menu.addAction(this->toolTip());
menu.addAction(this->whatsThis());
menu.exec(QCursor::pos());
Easiest way to show help when hover QWidget: setToolTip(QString) and setToolTipDuration(int).
If you want a "?" button, just implement your own QWidget. Then via ui designer or directly in your code add QPushButton and QLabel on layout, and show your QLabel with help text in position of cursor when clicked(). Something like this:
{
// Constructor
...
m_mainLabel = new QLabel("Main text");
m_button = new QPushButton("?");
m_helpLabel = new QLabel("Help text");
connect(m_button, SIGNAL(clicked(bool)),
this, SLOT(slotShowOrHideHelpLabel(bool)));
QHBoxLayout *hBoxLayout = new QHBoxLayout;
hBoxLayout->addWidget(m_mainLabel);
hBoxLayout->addWidget(m_button);
setLayout(hBoxLayout);
}
void slotShowOrHideHelpLabel(bool showHelpLabel)
{
if (showHelpLabel)
{
m_helpLabel->show();
m_helpLabel->move(QCursor::pos());
}
else
{
m_helpLabel->hide();
}
}

Coordinates of QPushButton in QList

I have created a QList of QPushButton that I have assigned to a slot function.
But I would like to get coordinates of the button which is clicked in the list.
For example, pushbutton n°5 is clicked, it return me (25,150).
listButton = new QList<QPushButton*>;
//some code here
QPushButton *button = new QPushButton(QString::number(1),ui->widget);
button->setGeometry(50, 50, 30, 30);
button->setStyleSheet("background-color:red;");
QObject::connect(button, SIGNAL(clicked()), this, SLOT(selectP()));
listeButton->append(button);
//some code here
void selectP()
{
//I'd like to print here, coordinates of the button which has called "selectP()"
}
Sorry for my language, thanks in advance !
In you slot you can get the pointer of the button that had been clicked:
void selectP()
{
QPushButton *btn = qobject_cast<QPushButton *>(sender());
if (btn) {
qDebug() << "The coordinates are:" << btn->geometry();
}
}

how to use mousePressEvent on QPushButtons

I've made some QPushbuttons like QPushButton **btn and I want to know when the user clicks on one of them using QMouseEvent here is the code but this idea does not work at all any ideas??
void Game::mousePressEvent(QMouseEvent *ev)
{
if(ev->button() == Qt::LeftButton)
{
btn[ev->x()][ev->y()].setStyleSheet("background-color : black;");
}
else
{
btn[ev->x()][ev->y()].setStyleSheet("background-color : red;");
}
that else part is for right click
and here is the code that generates the buttons
void Game::MakeButton()
{
btn = new ApButton*[column];
hrztl = new QHBoxLayout[column];
hrztl->setSpacing(0);
for(int i=0; i<column;i++)
{
btn[i] = new ApButton[row];
for(int j=0; j<row; j++)
{
btn[i][j].setRowCol(i,j);
btn[i][j].setFixedSize(50,50);
hrztl[i].addWidget(&btn[i][j]);
}
ui->MainLayout->addLayout(&hrztl[i]);
}
ui->MainLayout->setSpacing(0);
}
ApButton is a class that inherits QPushButton
This is a good example of use for a QSignalMapper, as seen there: http://qt-project.org/doc/qt-5.0/qtcore/qsignalmapper.html#details
ButtonWidget::ButtonWidget(QStringList texts, QWidget *parent)
: QWidget(parent)
{
signalMapper = new QSignalMapper(this);
QGridLayout *gridLayout = new QGridLayout;
for (int i = 0; i < texts.size(); ++i) {
QPushButton *button = new QPushButton(texts[i]);
connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(button, texts[i]);
gridLayout->addWidget(button, i / 3, i % 3);
}
connect(signalMapper, SIGNAL(mapped(QString)),
this, SIGNAL(clicked(QString)));
setLayout(gridLayout);
}
In that example, every button is identified by its title, as a QString. The mapper allows you to retrieve the corresponding button's title when one of them is clicked.
Switch your
Game::mousePressEvent(QMouseEvent *e)
to
ApButton::mousePressEvent(QMouseEvent *e)
since you are trying to implement the Press Event of the Button. If you only want to have the moment of the button being pressed and not changing Button behaviour with this, use a SIGNAL/SLOT connection instead of reimplementing the event (add to your creation):
connect(btn[i][j], SIGNAL(pressed()), this, SLOT(slotButtonPressed());
void Game::slotButtonPressed(){
//doSomething
}
use a QButtonGroup or the QSignalMapper if you need to identify more then one Button in a single method or use QObject::sender(), but this can be tricky sometimes.
I had a similar situations some times ago.. I had a QDialog and I had to dinamically add some QPushButton.. then I need to know on which button the user pressed.. so I needed something like:
connect( btn, SIGNAL( clicked(int) ),
this, SLOT( handle(int) ));
for instance a signal-slot connection with the id of the clicked button and a function for handle the click. The function is the same for each buttons and can handle the specific button because of the id..
Implementing this is quite simple subclassing QPushButton adding an id and a new signal..
Hope it's some help!
If Apbutton inherits QPushButton, why don't connect to clicked()?
then you can call QObject::sender()
On slot:
ApButton *but = dynamic_cast<ApButton*>QObject::sender()
if(but)
{
but->setStyleSheet("background-color : black;");
}
to get the clicked buttonbutton and set its stylesheet