Qt Designer Shortcut to another tab - qt

I was wondering if it were possible to create my own shortcut key to a QTabWidget. So if I put an ampersand infront of the letter, that means that ALT+'letter' will display that tab; however, I want it so that CTRL+'letter' will display that tab (not ALT).
Is there an easy way to do this in Qt Designer? If not, is there a simple way to do it in code? QTabWidget doesn't seem to have any direct methods for setting shortcuts.

I don't know of a way to do this via the Designer, not familiar with that. You could do it with QShortcut fairly easily in code though.
Here's a dummy widget to illustrate that. Press Ctrl+a / Ctrl+b to switch between tabs.
#include <QtGui>
class W: public QWidget
{
Q_OBJECT
public:
W(QWidget *parent=0): QWidget(parent)
{
// Create a dummy tab widget thing
QTabWidget *tw = new QTabWidget(this);
QLabel *l1 = new QLabel("hello");
QLabel *l2 = new QLabel("world");
tw->addTab(l1, "one");
tw->addTab(l2, "two");
QHBoxLayout *l = new QHBoxLayout;
l->addWidget(tw);
setLayout(l);
// Setup a signal mapper to avoid creating custom slots for each tab
QSignalMapper *m = new QSignalMapper(this);
// Setup the shortcut for the first tab
QShortcut *s1 = new QShortcut(QKeySequence("Ctrl+a"), this);
connect(s1, SIGNAL(activated()), m, SLOT(map()));
m->setMapping(s1, 0);
// Setup the shortcut for the second tab
QShortcut *s2 = new QShortcut(QKeySequence("Ctrl+b"), this);
connect(s2, SIGNAL(activated()), m, SLOT(map()));
m->setMapping(s2, 1);
// Wire the signal mapper to the tab widget index change slot
connect(m, SIGNAL(mapped(int)), tw, SLOT(setCurrentIndex(int)));
}
};
This isn't meant as an example of widget layout best practices... just to illustrate one way to wire a shortcut sequence to a tab change.

Related

How do you create a QPushButton in the MainWindow?

QPushButton* m_button = new QPushButton();
Whenever i try to create a QPushButton like this, it appears to be created in a new separate window. However, I want the Button to be created within the Mainwindow but I don't know how to do this (without using the Qt Designer).
You need to set the MainWindow as a parent
try this:
QPushButton* m_button = new QPushButton(this)

How To Create Tri-state Actions on Menus Using Qt

I have a situation where I need a tri-state checkable action on a QMenu, and the QAction class appears to only support on or off, unless I'm overlooking something obvious. The situation I have is a context menu where multiple objects are selected, but may have different states for a given boolean condition (i.e. for a given property, some objects have a true value and some false). I can leave the action unchecked when there's a mix of values, but I feel that's misleading to the user.
I'm using Qt 5.5.1 and very experienced with Qt, but not seeing a way to achieve what I want in this instance.
There is no direct way to do it from a QAction, but it is possible to subclass the QWidgetAction and create an action that contains a QCheckBox widget.
class CheckBoxAction : public QWidgetAction {
public:
CheckBoxAction (const QString &text) : QWidgetAction(Q_NULLPTR) {
QHBoxLayout *_layout = new QHBoxLayout(Q_NULLPTR);
QWidget *_widget = new QWidget(Q_NULLPTR);
QLabel *_label = new QLabel(text);
mCheckbox = new QCheckBox(Q_NULLPTR);
_label->setAlignment(Qt::AlignLeft);
_layout->addWidget(mCheckbox);
_layout->addWidget(_label);
_layout->addStretch();
_widget->setLayout(_layout);
setDefaultWidget(_widget);
}
QCheckBox *checkbox() {
return mCheckbox;
}
private:
QCheckBox *mCheckbox;
};
Simply use the class to then add to your menu; for instance:
CheckBoxAction *checkAction = new CheckBoxAction(QStringLiteral("My Action"));
checkAction->checkbox()->setCheckState(Qt::PartiallyChecked);
menu->addAction(checkAction);
You can use the checkbox() method in order to connect to signals when it changes; or change the checkbox state. Hope this helps.

close button on qDialog only closing on second click

I'm trying to generate a dialog that contains an ad-on tool that is separate from my main program, it its triggered from an action within the menus.
I've got the following code:
void MainWindow::on_actionCalibration_Tool_triggered()
{
QGridLayout *grid = new QGridLayout;
NewDialog.setLayout(grid);
NewDialog.setMinimumHeight(500);
NewDialog.setMinimumWidth(800);
QLabel *label = new QLabel;
QFont sansFont("MS Shell Dlg 2",22, QFont::Bold);
label->setText("Test");
label->setFont(sansFont);
QPushButton *okbutton = new QPushButton;
QPushButton *closebutton = new QPushButton;
okbutton->setText("Ok");
closebutton->setText("Close");
QTimer *timer = new QTimer;
connect(okbutton,SIGNAL(clicked()),this,SLOT(on_ScanpB_clicked()));
connect(closebutton,SIGNAL(clicked()),this,SLOT(CloseDialog()));
grid->addWidget(label);
grid->addWidget(okbutton);
grid->addWidget(closebutton);
NewDialog.exec();
NewDialog.show();
}
void MainWindow::CloseDialog()
{
NewDialog.close();
}
With NewDialog being defined in main window.h as a QDialog.
My issue is when I click the close button, the dialog will close for a split second then reopen, after I click the close button for a second time it closes for good.
Is there any better implementation or way around this?
Thanks
You should not call QDialog::show and QDialog::exec. Instead, pick one to call.
Use exec if you want to block user interaction with the dialog's parent while the dialog is open. The user will not be play with anything else in the application until they dismiss the dialog. This is called a modal.
Use show if you want to allow the user to work with the dialog and the rest of the application at the same time.
Usually you'd choose exec. It is easier to work with. In your case, you displayed the dialog twice by calling both functions.

How to build a simple custom widget with Qt?

How to build a simple custom widget with Qt? The widget is very simple with just 2 line edit QLineEdit' in a vertical box layoutQVBoxLayout`. How to do it? I read Qt's examples on custom widget generation. They reimplement paint event to rendering the custom widget. However, mine is so simple that I cannot find a solution in Qt's reference.
Well to do it all programatically it would look something like this:
class MyWidget : public QWidget {
public:
MyWidget(QWidget *parent=0) : QWidget(parent) {
QVboxLayout *layout = new QVboxLayout();
setLayout(layout);
layout->addWidget(new QLineEdit());
layout->addWidget(new QLineEdit());
}
};
Depending on your needs you could make the line edits member variables and manipulate them as you see fit.

How can I add another tab that looks exactly like the first one (like in a browser)?

I have a browser made in Qt and a I have a tabwidget with one tab (which has a label, lineedit and a webview). I want to add others that look like the first one (have label, lineedit and webview).
How can I do this?
I don't know of any way to "clone" or duplicate an existing tab or widget, so I believe you'll need to code the tab contents yourself (i.e. not through the designer).
If all you need are a QLabel, a QLineEdit and a QWebView, that's not very complex. The idea would be to:
create a custom widget (inheriting from QWidget directly, or from QFrame)
lay out the contained widgets in the fashion you want in its constructor
add as many tabs as you want, when you want them, via the QTabWidget.addTab function.
The Tab Dialog example has everything you need - it's actually more complex than what you need because it uses different widgets for each tab. You can get away with a single widget.
If you wonder how to do the layout, and you're satisfied with what you got from the designer, you can inspect the generated (.moc) files. You'll see what layouts it uses, and you can replicate that in your own code.
Skeleton widget:
class BrowserTab : public QWidet
{
Q_OBJECT
public:
BrowserTab(QUrl const& home, QWidget *parent = 0);
void setUrl(QUrl const& url);
private:
QWebView *web;
QLabel *title;
QLineEdit *urlEdit;
};
BrowserTab::BrowserTab(QUrl const& home, QWidget *parent)
: QWidget(parent)
{
urlEdit = new QLineEdit(this);
title = new QLabel(this);
web = new QWebView(this);
QVBoxLayout *vl = new QVBoxLayout;
vl->addLayout(title);
vl->addLayout(urlEdit);
vl->addLayout(web);
setLayout(vl);
setUrl(home);
}
void BrowserTab::setUrl(QUrl const& url)
{
web->load(url);
// update label & urlEdit here
}
You'll need to do a bit more to make it a proper browser (setUrl should probably be a slot too), but this should get you started.

Resources