this is the first time i write in this site, I'm trying approach me at Qt-creator but I've a problem:
I want to delete the text of the label when the user click a button, i've tried some solution but without success
this is the code:
struct finestra{
float costo;
int altezza;
int larghezza;
QString text;
QString costoStr;
};
float Totale=0;
finestra vet[21];
int i=1;
//SOME CODE
Totale+=vet[i].costo;
vet[i].costoStr = QString::number(vet[i].costo);
vet[i].text = vet[i-1].text + "Finestra ad un anta bianca <br>" + "€" + vet[i].costoStr +"<br>";
ui->TotaleFinestre->setText(QString(vet[i].text));
i++;
I've tried with this function:
void preventivi::on_pushButton_clicked()
{
ui->TotaleFinestre->clear();
}
if someone know how to do please answer,
thanks to all and sorry for my bad english.
Maybe you should try
void preventivi::on_pushButton_clicked()
{
ui->TotaleFinestre->setText("");
}
As QLabel define the slot void QLabel::clear(), you can also just connect this slot with the clicked() signal that will be emitted after a click on your pushButton, using the QObject::connect method :
QObject::connect(pointer_to_your_pushButton, SIGNAL(clicked()), pointer_to_your_label, SLOT(clear()));
EDIT : Here is a small example
The UI is a QWidget that has a QLabel and a QPushButton. I did that with Qt Designer but it doesn't matter here.
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
QObject::connect(ui->pushButton, SIGNAL(clicked()), ui->label, SLOT(clear()));
}
Widget::~Widget()
{
delete ui;
}
You can even do that using "Edit Signals/Slots" inside Qt Designer and make the signal/slot connection between your widgets. ( you won't need to manually call the previous QObject::connect, as it will be done automatically inside the Ui_Widget class, generated by the uic)
Or you can do all without Qt Designer, it's up to you.
Hope this helps.
Related
I have the following code:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
mUi(new Ui::MainWindow)
{
mUi->setupUi(this);
this->setFixedSize(this->width(), this->height());
StyleUi();
auto closeAct = new QAction(this);
closeAct->setShortcut(QKeySequence("Ctrl+O"));
connect(closeAct, SIGNAL(activated()), this, SLOT(close()));
closeAct->setShortcutContext(Qt::ApplicationShortcut);
addAction(closeAct);
}
The last 5 lines define a QAction with a shortcut created from the sequence Ctrl+O, connects the QAction the the slot Close(). I've found this example here on stackoverflow and several other documentation sites describe what I want to do as such. However, I am not getting anywhere with this. My program doesn't close when I hit Ctrl+O. Any suggestions on where I am doing something wrong?
You can create it by using the multiple arguments constructor for QKeySequence.
like this:
QShortcut *shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_O), this);
shortcut->setContext(Qt::ApplicationShortcut);
And try this to get QShortcut signal activated:
connect(shortcut, &QShortcut::activated, this, &MainApp::activeShortcut);
void MainApp::activeShortcut()
{
this->close();
}
This is a sample project for your question on github download here.
I want to know how can I open a popup menu when I right click on the table items. In the popup menu some actions like add and delete should be given, which will create a new row or delete the selected row.
I am a new in the Qt world, so if anybody can give me the full details (with code if possible) then I will be really grateful towards him/her.
Thank you.
My goal: Only in the area of QListWidget and only if you click on an item, the menu with Delete will be opened.
Edit : Ok I solved the problem with the QListWidget and the menu. Now the following must be accomplished:
If you click on an item with the right mouse button, and then click Delete, then the item will be deleted.
My code:
void ProvideContextMenu(const QPoint &); // MainWindow.h
// In MainWindow.cpp
ui->listFiles->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->listFiles, SIGNAL(customContextMenuRequested(const QPoint &)),
this, SLOT(ProvideContextMenu(const QPoint &)));
void MainWindow::ProvideContextMenu(const QPoint &pos)
{
QPoint item = ui->listFiles->mapToGlobal(pos);
QMenu submenu;
submenu.addAction("ADD");
submenu.addAction("Delete");
QAction* rightClickItem = submenu.exec(item);
if (rightClickItem && rightClickItem->text().contains("Delete") )
{
ui->listFiles->takeItem(ui->listFiles->indexAt(pos).row());
}
}
Edit2 : Ok I solved the whole problem :D. I uploaded my code, if somebody needs something like that it can help him/her.
Firstly you need to create slot for opening context menu:
void showContextMenu(const QPoint&);
At constructor of your class, which used QListWidget, set context menu policy to custom and connect QListWidget::customContextMenuRequested(QPoint) signal and showContextMenu() slot like this:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
setupUi(this);
listWidget->setContextMenuPolicy(Qt::CustomContextMenu);
connect(listWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint)));
}
Then need to realize context menu opening:
void MainWindow::showContextMenu(const QPoint &pos)
{
// Handle global position
QPoint globalPos = listWidget->mapToGlobal(pos);
// Create menu and insert some actions
QMenu myMenu;
myMenu.addAction("Insert", this, SLOT(addItem()));
myMenu.addAction("Erase", this, SLOT(eraseItem()));
// Show context menu at handling position
myMenu.exec(globalPos);
}
After this we need to realize slots for adding and removing QListWidget elements:
void MainWindow::eraseItem()
{
// If multiple selection is on, we need to erase all selected items
for (int i = 0; i < listWidget->selectedItems().size(); ++i) {
// Get curent item on selected row
QListWidgetItem *item = listWidget->takeItem(listWidget->currentRow());
// And remove it
delete item;
}
}
As you can see we iterate all selected items (for set multiple selection mode use setSelectionMode() method) and delete it by ourself, because docs says that
Items removed from a list widget will not be managed by Qt, and will
need to be deleted manually.
Adding some items is easier, my solution with static variable for different item caption looks like:
void MainWindow::addItem()
{
static int i = 0;
listWidget->addItem(QString::number(++i));
}
To simplify your code use Qt5 sytax for signals and slots. It eliminates the need to create intermediate slots.
I hope it helps to you.
It's much simpler than the accepted answer. You don't need to deal with creating a context menu or cursor positions or any of that. Instead of Qt::CustomContextMenu, use Qt::ActionsContextMenu and just add your actions directly to the widget:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
ui->setupUi(this);
// you can create the actions here, or in designer
auto actInsert = new QAction("Insert", this);
auto actDelete = new QAction("Delete", this);
// you can set up slot connections here or in designer
connect(actInsert, SIGNAL(triggered()), this, SLOT(addItem()));
connect(actDelete, SIGNAL(triggered()), this, SLOT(eraseItem()));
// and this will take care of everything else:
listWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
listWidget->addActions({ actInsert, actDelete });
}
void MainWindow::addItem () {
...; // add an item
}
void MainWindow::eraseItem () {
...; // erase an item
}
Everything above except addActions (I think) can also be done in Designer.
Alternatively, if you don't want to add actual slot functions for whatever reason, you can do everything in a lambda on connect, too:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
ui->setupUi(this);
// you can create the actions here, or in designer
auto actInsert = new QAction("Insert", this);
auto actDelete = new QAction("Delete", this);
connect(actInsert, &QAction::triggered, [=]() {
...; // add an item
});
connect(actDelete, &QAction::triggered, [=]() {
...; // erase an item
});
// and this will take care of everything else:
listWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
listWidget->addActions({ actInsert, actDelete });
}
The signal/slot option is more organized and flexible, but the lambda option is good for short highly specialized bits of code (or binding to functions that aren't slots).
This works for context menus on any widget. Also, the same QAction can be used on multiple widgets.
I'm learning the signals/slots in Qt and I have found a problem. I need to create my own slot that is called when items on QGraphicsScene (in QGraphicsView) are moved or selected.
I'm starting with a simple app that has one widget and on it is graphicsView and label. I've created a slot in my window and connected it to QGraphicsScene's signal, but it is not being used. Where is my mistake?
Here is the code:
//MainWindow.h
//as generated by QtCreator, just added one slot to it
...omitted for brevity...
public slots:
void selectedItemChanged(QGraphicsItem * newItem, QgraphicsItem * oldItem);
..omitted for brevity...
//------------------------------------------------------------------
//MainWindow.cpp
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
QGraphicsScene * scene = new QGraphicsScene();
scene->setBackgroundBrush (QBrush(Qt::gray));
ui->graphicsView->setScene (scene);
for(int x = 10; x < 250; x+=20)
{
QGraphicsEllipseItem * item = scene->addEllipse (x,x,5,5,QPen(Qt::darkGreen),QBrush(Qt::darkGreen));
item->setFlag (QGraphicsItem::ItemIsFocusable,true);
}
QObject::connect (scene,SIGNAL(focusItemChanged),this,SLOT(selectedItemChanged));
}
void MainWindow::selectedItemChanged (QGraphicsItem *newItem, QGraphicsItem *oldItem)
{
qDebug()<<"called";
if(newItem == 0)
{
ui->label->setText ("Není vybrán bod");
}
else
{
ui->label->setText (QString::number (newItem->scenePos ().x ()) + "," + QString::number (newItem->scenePos ().y ()));
}
}
Now, when I run the probram it rins ok, but I cannot set Focus on the circles(ellipses) drawn on the scene and the slot is not used. I tried setting IsSelectable flag, but it does not help. Is there any other preferred way to get this done or solution to my problem?
You're not linking against the signal's right signature, according to the documentation:
void QGraphicsScene::focusItemChanged( QGraphicsItem * newFocus, QGraphicsItem * oldFocus,
Qt::FocusReason reason)
and also notice that you can check the connection's success/failure status via the bool return type of the QObject::connect method
So, in the end i found the answer to my own question. It was a mistake on my side.
in the connect() i used the slots without parenthesis/parameters. It should have looked like:
QObject::connect (scene,
SIGNAL(focusItemChanged(QGraphicsItem*,QGraphicsItem*,Qt::FocusReason)),
this,
SLOT(selectedItemChanged(QGraphicsItem*,QGraphicsItem*)));
I have code like below. I have some data in database and I need to create view structure to display it. I don't have big experience in Qt programming, I've made more things in PHP, HTML and CSS. I need to do something like in HTML - when you have a box (for example div) without extra style and you put inside some data this div tag will display all data's inside. But with following code I've got only a part of datas from widgets loaded from file. Behavior of GridLayout in MainWindow is similar to div style="max-width: 200px; max-height: 200px; overflow:hidden". And also Layout elements from children's file has the same behavior...
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "databasemanager.h"
#include "ycexception.h"
#include <QDebug>
#include <QSqlQuery>
#include <QtUiTools>
#include <QLabel>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
createStructureFromDb();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::createStructureFromDb() {
try {
dbManager = new DatabaseManager();
}
catch(YCException e) {
//TODO: show dialog with message
qDebug() << e.what();
exit(-1);
}
QSqlQuery groupsQuery = dbManager->getGroups();
while(groupsQuery.next()) {
Group group;
group.setIdGroup(groupsQuery.value(0).toInt());
group.setName(groupsQuery.value(1).toString());
QUiLoader loader;
QFile file(":/forms/group.ui");
file.open(QFile::ReadOnly);
QWidget *formWidget = loader.load(&file);
file.close();
(formWidget->findChild<QLabel*>("groupName"))->setText(group.getName());
ui->gridLayout->addWidget(formWidget);
QVBoxLayout* groupItems = formWidget->findChild<QVBoxLayout*>("groupItems");
QSqlQuery cardsQuery = dbManager->getGroupCards(group.getIdGroup());
while(cardsQuery.next()) {
Card card;
card.setIdCard(cardsQuery.value(0).toInt());
card.setContent(cardsQuery.value(1).toString());
card.setDueDate(cardsQuery.value(2).toString());
card.setIdGroup(cardsQuery.value(3).toInt());
group.addCard(card);
QFile file(":/forms/card.ui");
QWidget *cardWidget = loader.load(&file);
file.close();
(cardWidget->findChild<QLabel*>("contentLabel"))->setText(card.getContent());
(cardWidget->findChild<QLabel*>("dueDateLabel"))->setText(card.getDueDate());
groupItems->addWidget(cardWidget);
}
groups.insert(group.getIdGroup(), group);
}
ui->label->setText("really long textreally long textreally long textreally long textreally long textreally long textreally long textreally long textreally long textreally long textreally long text");
this->layout()->activate();
}
overflow:hidden is all but explicit for persons like me that have only a very little knowledge of web technologies (but I can google it). But, saying that you want scrollbars is a lot more expressive... I used this page to understand what you want.
So, for what you want: GridLayout is not like html's div. If you want the content of a widget to be scrolled, you have to put the widget in a QScrollArea, and put that scroll area in the cell of the GridLayout that first contained your widget.
More specifically:
overflow:visible : not possible
overflow:hidden : default behavior
overflow:scroll : use QScrollArea
overflow:auto : use QScrollArea
overflow:inherit : possible, but you need to write quite a bit of code to do this. Also, useless in a well-designed interface
i am creating a software using C++ and QT,and i have two widget one of type QRadioButon and one QTabWidget. My need is that i want to send signal from a radio button and i want that whenever the button is checked the content of tab get changed.
Can anyone suggest how to do that? I tried creating a slot of my widget class and in that slot i called the constructor of tab class but the problem is the construtor is not getting called.
here is the code i am using..
#include <QtGui>
#include "v_lab.h"
v_lab::v_lab(QWidget *parent)
: QDialog(parent)
{
setWindowTitle("Virtual Lab");
maingroup=new QGroupBox(this);
maingroup->setTitle("Algorithms");
maingroup->setMinimumWidth(200);
maingroup->setMaximumWidth(240);
maingroup->setFlat(false);
p=new QPalette;
p->setColor(QPalette::Background,QColor(233,212,102));
setPalette(*p);
box=new QGroupBox(maingroup);
box->setFlat(false);
box->setTitle("Searching Algorithm");
linear_search=new QRadioButton("Linear Search",box);
linear_search->setChecked(1);
binary_search=new QRadioButton("Binary Search",box);
box1=new QGroupBox(maingroup);
box1->setFlat(false);
box1->setTitle("Sorting Algorithms");
bubble_sort=new QRadioButton("Bubble Sort",box1);
selection_sort=new QRadioButton("Selection Sort",box1);
box2=new QGroupBox(maingroup);
box2->setFlat(false);
box2->setTitle("Tree Algorithms");
infix_traversal=new QRadioButton("Infix Traversal",box2);
prefix_traversal=new QRadioButton("Prefix Traversal",box2);
postfix_traversal=new QRadioButton("Postfix Traversal",box2);
box3=new QGroupBox(maingroup);
box3->setFlat(false);
box3->setTitle("Graph Algorithms");
bfs=new QRadioButton("BFS",box3);
dfs=new QRadioButton("DFS",box3);
shortest_path=new QRadioButton("Shortest Path",box3);
QString string1="go to hell";
tab=new QTabWidget;
tab->addTab(new algorithm(string1),"Algorithm");
// tab->addTab(new psudo_code(),"Pseduo-Code");
tab->setMinimumWidth(250);
tab->setMaximumWidth(400);
//Layout
mainlayout=new QHBoxLayout(this);
mainlayout->addWidget(maingroup);
mainlayout->addWidget(tab);
mainlayout->addStretch();
main_left_pane_layout=new QVBoxLayout(maingroup);
main_left_pane_layout->addWidget(box);
main_left_pane_layout->addWidget(box1);
main_left_pane_layout->addWidget(box2);
main_left_pane_layout->addWidget(box3);
left_pane_box=new QVBoxLayout(box);
left_pane_box->addWidget(linear_search);
left_pane_box->addWidget(binary_search);
left_pane_box1=new QVBoxLayout(box1);
left_pane_box1->addWidget(bubble_sort);
left_pane_box1->addWidget(selection_sort);
left_pane_box2=new QVBoxLayout(box2);
left_pane_box2->addWidget(infix_traversal);
left_pane_box2->addWidget(prefix_traversal);
left_pane_box2->addWidget(postfix_traversal);
left_pane_box3=new QVBoxLayout(box3);
left_pane_box3->addWidget(bfs);
left_pane_box3->addWidget(dfs);
left_pane_box3->addWidget(shortest_path);
connect(binary_search,SIGNAL(clicked()),this,SLOT(peeyush()));
}
algorithm::algorithm(const QString &string,QWidget *parent)
: QWidget(parent)
{
label=new QLabel(string);
main_layout=new QVBoxLayout;
main_layout->addWidget(label);
main_layout->addStretch();
setLayout(main_layout);
}
/*
psudo_code::psudo_code(QWidget *parent)
: QWidget(parent)
{
label1=new QLabel("Hello Peeyush Chandel");
main_layout1=new QVBoxLayout;
main_layout1->addWidget(label1);
main_layout1->addStretch();
setLayout(main_layout1);
}
*/
void v_lab::peeyush()
{
QString string1="new string";
algorithm obj(string1);
//exit(1);
}
In the header definition file of your v_lab class you should have something like this:
// Includes here.
class v_lab: public QDialog
{
Q_OBJECT // VERY important!
public:
// Other things here.
private slots: // VERY important. You can use public slots too.
void peeyush();
}
And you cannot connect a signal to a constructor.