How to set different icons to different buttons in Qt? - qt

I have a lot of buttons that I want to set an icon to. Moreover, this icon is not the same for each button.
I do this just for one of them:
QString str=(qApp->applicationDirPath());
str.append("/pic/kb.png");
QPixmap pixmap(str);
QIcon ButtonIcon(pixmap);
ui->btnShowKB->setIcon(ButtonIcon);
ui->btnShowKB->setIconSize(pixmap.rect().size());
but I really have a lot of button (btn1,btn2,btn3,....,btn9).
How can I set other images for other buttons (/pic/1.png , /pic/2.png , /pic/3.png , .... , /pic/9.png)?
Do I have to create a new QPixmap for each one, or is there a simpler solution?

First of all, if you're using designer, so use it fully, not only for adding widgets. You can add icon to your buttons from there. Just add resource file to your project, load images to it and then choose needed to buttons. Or, if you don't want use resource file, you can upload images from any directory.

The way you are doing it, the only things that change in your code is obviously the name of the file and the button you want to set an icon to. So you should create a method taking a QString and a button as parameters, and call it whenever you need it for your desired button. (In the below code, I use a QPushButton as a button, maybe it is different for you so change it accordingly).
void yourClass::setButtonIcon(QString iconPath, QPushButton* button)
{
qApp->applicationDirPath().append(iconPath);
QPixmap pixmap(str);
QIcon buttonIcon(pixmap);
button->setIcon(ButtonIcon);
button->setIconSize(pixmap.rect().size());
}

Related

How can I tell QWidget to show in the same place that it was before it was hidden?

If I create and show a top-level QWidget, drag it to a new position on the desktop, then call widget->hide() followed by widget::show(), it generally reappears in a different place from where it was previously.
I can add code to the subclass which saves and restores its geometry, but I'm wondering if there's an in-Qt system for giving hints to the window manager as to where the widget should appear when shown.
Is there a nice way to do this?
I create a "Qt Widgets Application" and drag in a QPushButton, then add the following code:
void Widget::on_pushButton_clicked()
{
hide();
show();
}
Run the program, drag the widget to a new position, and then click on the button and I find that the widget is still in the same place, not like you said

How to keep a pushButton of Qt be down after I click it?

I would like to implement a group of pushButtons like painting tool chose in Adobe Ps:
only one button can be checked at any time
keep button be down after I click it
I have used setAutoExclusive(true) to meet the first requirement. So the next step is to deal with the second... Please give me some advice or suggestion?
QPushbutton button;
button->setCheckable(true);
or just click on the "Checkable" check box in designer
Like suggested by another answer, you can create a QPushButton by e.g.
button = new QPushButton("Button text", this);
and then make it checkable with
button->setCheckable(true);
For this to have a visual effect, you need a section in your stylesheet (.qss) for
QPushButton:checked. If you have a section for QPushButton:pressed, you can just add it there, i.e. change
QPushButton:pressed {
to
QPushButton:pressed,
QPushButton:checked {
If you don't, the styling you need depend on the appearance of the button in its pressed state, which in turn depends on your operating system, so you have some guesswork to do.

How can I customize the appearance of the actions in my QToolBar?

I have just changed some toolbars from Q3ToolBars (with QToolButtons explicitly added to them) into Q4 toolbars (with actions added to them straight away instead.)
The old tool buttons had a nice outline around them, but this is not displayed in the new version; the QActions in the Q4 toolbar just look like a line of icons. Is there a way to change the 'button' style in the new version (assuming these actions can be considered as such) and give them the outline? I've looked through the QToolBar reference, but the toolButtonStyle() function only appears to work with whether you want to display icon, text, etc.
...Or will I have to just make actual tool buttons and/or QPushButtons and use addWidget()?
The widget associated with a given action is accessible through QToolBar::widgetForAction (since Qt 4.2). So, you can pass your actions to this method, get the QWidgets returned by it, convert them to QToolBar, and handle them like you normally would (code not tested):
// ...
auto toolButton =
static_cast<QToolButton *>(
m_ui.toolbar->widgetForAction(m_ui.my_Action));
// Will make the toolButton always appear raised:
toolButton->setAutoRaise(false);
// ...
As far as I've been testing, some methods might not work (i.e., QWidget::hide), so do your own testing.
Yes, of course you can edit look of QToolButtons in two different ways:
You can set it style sheet using void QWidget::setStyleSheet(const QString &)
You can reimplement QToolButtons class with new paintEvent function where you will be able to exactly set how your button should looks like.

Qt4: QLabel -> QPixmap -> click to open URL

I have a QLabel without any text but with a QPixmap image. I can not figure out a way to open a url when the user clicks the image. I can not use text in QLabel here.
You don't need to put text in, but you do need to switch to either a subclassed label or to use a QPushButton instead. If you use a QPushButton (which is the easiest) then you can change the relief layout so it looks flat again (since the default button doesn't).
You could install an event filter on the label and filter for mouse press events. For an example, see my answer to a similar question.

Paste event in Qt

I want to build a structured document editor using Qt. The base concept for v1 is nested sections, each section having a title and one or more paragraphs. Sections and paragraphs are distinct visual units (probably via background shading). I also need to be able to store character-level semantics (ie: this run of text is associated with reference X). If I wanted to build a read-only view of this it would be doable with QFrame for the sections and a QLabel for each title and each paragraph. To make this editable I'm pretty sure I can capture all keyboard events to the window and implement a cursored text-entry-and-editing feel that way.
What I'm having trouble with is how to handle copy/paste.
I want the clipboard interactions to feel native: that is, ctrl+c/v on window, command+c/v on OSX, ctrl+c/v for clipboard on X, select to copy for PRIMARY on X, middle click to paste for PRIMARY on X, etc.
The standard text editing controls in Qt handle all of this just fine. I'm wondering if there is some sort of "paste event" or similar that I can grab to implement the same thing in my custom widget? Is there another way?
For native keyboard shortcuts, you can add them to menu items:
ui->actionCut->setShortcut(QKeySequence::Cut);
ui->actionCopy->setShortcut(QKeySequence::Copy);
ui->actionInsert_empty_row->setShortcut(Qt::Key_Insert);
ui->actionPaste->setShortcut(QKeySequence::Paste);
ui->actionRemove->setShortcut(QKeySequence::Delete);
See QKeySequence docs
There's no paste signal/event as far as i know to listen to, though there's nothing stopping you from taking a sneak look at how the paste() slot is implemented in widgets like QLineEdit and implement your own if possible. The afferent signal is not that important, since it's just a signal and you can trigger that whenever you desire(eg. Ctrl+v, context menu or program menu).
LE: If i think better, you might be thinking this the wrong way, you don't need a signal, you just need the slot that you can call whenever the action is called by any means you wish(eg. ctrl+v). Once you have the slot(QClipboard), it's just a matter of properly connecting it to the desired triggering actions/signals.
I'm not completely sure why you would want to do it with a QLabel and then capture the keys when there are already classes that handle text edition for you (and you can even override the key pressed funcionality)
If you want to have editable text, you could use a QTextEdit or a QPlainTextEdit and those classes already handle the copy-paste functionality (even with right click menu and everything).
If you want to add special a special behavior to your copy and paste, you can override the Mime functions:
//in your header file, add
void insertFromMimeData(const QMimeData *source) override; // override for paste
QMimeData * createMimeDataFromSelection() const override; // override for copy
// in the cpp:
//it would be something like this:
void YourTextField::insertFromMimeData(const QMimeData *source) {
// Do something special on the paste event, maybe even create your own "source"
//call the base class insert
QPlainTextEdit::insertFromMimeData(source);
}
Note: I'm not 100% with the copy, since I only overrode paste, but I'm almost certain that that's the right function.

Resources