I am a beginner in QT gui c++ programming. i am trying to load a picture on button click using a pushbutton and label.
inside my mainwindow.cpp , i only added the following.
void MainWindow::on_pushButton_clicked()
{
QPixmap pix("C:/Users/Public/Pictures/Sample Pictures/Chrysanthemum.jpg");
ui->img_label->setPixmap(pix);
}
. thats all wat i added in the code. program compiles fine but when it runs, it just shows a portion of image instead of showing the full image. can anyone help. Without even adding to the resources,it showed atleast a part of the image.
you can try using PNG - as depending on your Qt version some plugins are needed for JPG. You should also make the pixmap a member of your class.
You can scale your image to specific size something like that:
void MainWindow::on_pushButton_clicked() {
QPixmap pix("C:/Users/Public/Pictures/Sample Pictures/Chrysanthemum.jpg");
ui->img_label->setPixmap(pix.scaled(my_width, my_height,
Qt::KeepAspectRatio, Qt::SmoothTransformation));
}
If you don't want scale, tell us what layout manager do you use?
Related
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
In any Qt application on KDE when I add a QPushButton in designer and check it's text by:
void MainWindow::on_pushButton_clicked()
{
qDebug()<<ui->pushButton->text();
}
The output is preceded by an & :
&PushButton
This behavior does not exist on Windows. It seems that Qt applications on KDE automatically add shortcuts to all push buttons, which is not desired for me. I should note that the ampersands are not created by designer and you can not see them in the.ui file. Actually when the button is added to a widget, an & is placed somewhere in it's text.
Is it possible to disable automatic mnemonics of a Qt application in anyway?
KDEPlatformTheme plugin responsible for it.
A workaround is to add
[Development]
AutoCheckAccelerators=false
to ~/.config/kdeglobals, which prevents KDE from automatically adding accelerators.
Related bug: https://bugs.kde.org/show_bug.cgi?id=337491
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());
}
I recently installed Github for Windows on my Windows 7 machine and loved the custom frame it had, it fit really well with the overall application theme and had it's own titlebar buttons which were really well layed out, very fluent, and seemed very natural to work with.
I did a bit of digging and found 2 flags that would clear out the border completely and after a bit of customization I got my app to also have a nicely customized look which was intuitive yet different from all the apps with the old Windows border.
The thing was it wasn't fluent and naturally responsive like the other windows, it was glitchy as heck, I easily got the window to move around with the mouse but it often glitched and was able to be moved on areas it shouldn't like clicking and dragging on a disabled button.
The maximize button which was linked to showMaximize method just enlarged the whole window to take up the entire desktop, you could still move it (wasnt really trully maximized).
The window responded to none of the system signals like clicking the taskbar to minimize it and such.
After a lot of fixing around I just finally gave up which was ashame cause I really liekd how it looked and it was very intuitive, much like github for Windows is very intuitive.
Is there any way I can accomplish this, I'm really not ready to give up yet.
I know that when making a raw Windows API application you have to link it to the XP built-in style because it inherits the Windows 95 style by default, maybe theres a Windows 8 style that Qt'S not connected to, I do't know didn'T go that far in research yet.
Minimize window by clicking on task bar
It seems that Qt::FramelessWindowHint's implementation is limited. When this flag is set, Windows thinks that this window cannot be minimized or maximized. I've tried this solution implemented in pure winapi. Minimizing and restoring frameless window by clicking on taskbar works fine. Apparently Qt sets some bad flags that block this functionality. May be there is a good reason for that, I don't know.
We can use winapi and Qt together but it is troublesome. Firstly, winapi code should be executed after you set window flags and show the window using Qt. Otherwise Qt will overwrite window flags.
Another problem is when we remove border using winapi, window geometry suddently changes, and Qt doesn't know about that. Rendering and event mapping (including mouse click positions) become invalid. I didn't find any documented way to update mapping. I've found that we can tell Qt that screen orientation has changed, and it forces it to recalculate window geometry. But this looks like a dirty hack. Also the QWidget::windowHandle function is missing in Qt 4 and "is subject to change" in Qt 5. So this method is not reliable. But anyway, it works now. Here is complete code (tested in Windows 8) that should be placed in the top window class constructor:
#include "windows.h"
#include <QWindow>
//...
show();
HWND hwnd = reinterpret_cast<HWND>(effectiveWinId());
LONG lStyle = GetWindowLong(hwnd, GWL_STYLE);
lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU);
SetWindowLong(hwnd, GWL_STYLE, lStyle);
setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
windowHandle()->reportContentOrientationChange(Qt::PrimaryOrientation);
The true way to solve this problem is to modify the Window Qt platform plugin (see QWindowsWindow class in Qt sources). May be there is a way to inherit from the default implementation, modify it and use in your app. Also you can ask Qt developers is this behavior reasonable or is it a bug. I think that this issue can be fixed with a patch.
If you still intend to use this code and other OSs should be also supported, don't forget to wrap windows-specific implementation in #ifdef Q_OS_WIN.
Enable window dragging only when title bar is clicked and window is not maximized
Other problems can be fixed more easily. When you process mouse events to implement window dragging, check window state and event position and disable moving when it is unwanted.
void MainWindow::mousePressEvent(QMouseEvent *e) {
if (!isMaximized() &&
e->button() == Qt::LeftButton &&
ui->title->geometry().contains(e->pos())) {
window_drag_start_pos = e->pos();
}
}
void MainWindow::mouseReleaseEvent(QMouseEvent *e) {
window_drag_start_pos = QPoint(0, 0);
}
void MainWindow::mouseMoveEvent(QMouseEvent *e) {
if (!window_drag_start_pos.isNull()) {
move(pos() + e->pos() - window_drag_start_pos);
}
}
void MainWindow::on_minimize_clicked() {
showMinimized();
}
void MainWindow::on_maximize_clicked() {
if (isMaximized()) {
showNormal();
} else {
showMaximized();
}
}
Here ui->title is a label used for displaying fake title bar, and QPoint window_drag_start_pos is a class variable.
If you use Qt::FramelessWindowHint, you lose all Windows frame related features, such as docking, shortcuts, maximizing, etc. You can implement some of them yourself, with great effort in some cases, but other things will still just not work, including handling multiple monitors and all the capabilities of the Windows Key. If you need your app to behave like a regular Windows app, Qt::FramelessWindowHint is pretty much a dead end.
The only real solution is to use the DWM API that Windows provides for this purpose, Custom Window Frame Using DWM. They provide examples of how to do anything you might want in the frame area, while preserving all the standard windows-manager behaviors.
Applications such as Chrome do use DWM for this (see the AeroGlassFrame class in the Chromium source). Granted, Chrome isn't using Qt, so it doesn't have to do the work of sneaking around QMainWindow to handle the Windows-specific messages, and their code has plenty of comments that indicate how messy it is, like:
// Hack necessary to stop black background flicker, we cut out
// resizeborder here to save us from having to do too much
// addition and subtraction in Layout() ...
Similarly, the Github-for-Windows app you mention is built on a platform called Electron, which in turn uses, you guessed it, DWM.
I haven't found any working example of a DWM frame around a Qt application, but hopefully this provides a starting point.
I am creating a GUI using Qt. Basically it is an interactive map that shows robots moving in an arena in real time and allows the user to interact with the robots(tell them to go/stop) by using the mouse and keyboard keys. I used opengl to create the map itself and everything is working perfectly, I can see the robots moving on the map and I can press different keys on the keyboard and send the actual robots commands.
Now, I need to take this map and make it become a part of a bigger GUI that holds this map along with other objects as well,not all objects are necessarily using opengl. So, by using the Qt creator (designer) I have some dragged/dropped tabs in my GUI and I have also added a "dockwidget" in my GUI. The dockwidget holds in it the interactive map that I had created earlier. Now, however I can no longer send commands using my keyboard to my map. I can still click on different robots on my map and I can see that they get selected and change colors (as I coded it to do) but pressing keys have no corresponding actions(as it has been coded).
This is what the map by itself looks like. http://dl.dropbox.com/u/46437808/collision3.png
This is the map as a docked widget. (Inside the widge,I was able to click on one robot and make it turn yellow) https://www.dropbox.com/s/lpo43rl6z4268im/argHRI.png
So, my question is how do we direct keyboard input to a specific widget in a window when using Qt. From what I read that it might have to do with setting focus policy. So, I tried to set the focuspolicy of my dockwidget to "StrongFocus" (so that it can take keyboard input) in the constructor but that did not help.
Here is the code in which I'm setting my map as the dockwidget and I'm trying to set the focus as well.
#include "ui_arghri.h"
argHRI::argHRI(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::argHRI)
{
ui->setupUi(this);
ui->dockMap->activateWindow();
//ui->dockMap->keyboardGrabber();
//ui->dockMap->grabKeyboard();
ui->dockMap->setFocus();
ui->dockMap->setFocusPolicy(Qt::StrongFocus);
}
argHRI::~argHRI()
{
delete ui;
}
void argHRI::addMap(Map * map)
{
qDebug()<<"argHRI::in AddMap test is "<<map->test;
//ui->dockMap->show();
ui->dockMap->setWidget(map);
}
Add an event filter that handles KeyPress events to your class. There are examples here: http://doc.qt.io/archives/qt-4.7/eventsandfilters.html
Just don't forget to add:
installEventFilter(this);
to the constructor or it won't work otherwise.