Show QWidget with QSlider on top of tray icon - qt

I'm trying to implement some kind of volume slider in Qt.
I have added the QWidget with a QSlider on it. It works
fine for me... But! QWidget shows on the screen center.
But I need it on top of the tray icon.
Does anybody knows how to do that?
Code:
VolumeSlider::VolumSlider(QWidget *parent) : QWidget(parent)
{
setWindowFlags(Qt::Popup);
resize(20, 150);
slider = new QSlider(Qt::Vertical, this);
slider->setRange(0, 100);
slider->setSingleStep(5);
slider->setPageStep(10);
slider->setValue(currentVolume);
slider->resize(20, 150);
}
I'm showing the QWidget witha QSlider on middle click:
connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
this, SLOT(trayIconClicked(QSystemTrayIcon::ActivationReason)));
And a slot implementation is:
void VolumeSlider::trayIconClicked(QSystemTrayIcon::ActivationReason reason)
{
if (reason == QSystemTrayIcon::MiddleClick) {
show();
}
}
Thank you for your attention!
Best regards!

You may consider the QSystemTrayIcon Class:
http://doc.qt.io/qt-5/qsystemtrayicon.html
And this example:
http://doc.qt.io/qt-4.8/qt-desktop-systray-example.html

Related

Allow Close Option in Taskbar When QDialog is Open above QMainWindow

I have tried with setModel(false) but that is not the solution allowing that hampering other functionalities .So Now
I have one QMainwindow and QDialog pops up after clicking button on QMainwindow and I want to close the QMainWindow from Taskbar.
void on_btnShare_clicked()
{
auto hilightReelDlg = new HighlightReelDialog( this->highlightManager,
this->soloshotAnalyzer->getNoVideoArea(),
this->videoFilePaths,
this->SortingOptions,
this );
ui->btnShare->setEnabled(false);
if (hilightReelDlg != NULL )
{
int NumberHilights = this->mainAppLinker->getHighlightJumper()->getActiveHighlightCount();
ui->hilightProgressBar->setMaximum(NumberHilights);
QObject::connect(hilightReelDlg, &HighlightReelDialog::send_Init_Progress, this, [=](int inc)
{
on_Hilight_Init_Progress(inc);
});
QObject::connect(hilightReelDlg, &HighlightReelDialog::initialization_finished, this, [=]() { on_Hilight_Init_Finished(); });
hilightReelDlg->ProcessVideoPlayers();
//QDesktopWidget Class
QDesktopWidget desk;
QRect screenres = desk.screenGeometry(0);
hilightReelDlg->setGeometry(QRect(0.10*screenres.width(), 67, 0.79*screenres.width(), 0.86*screenres.height()));
hilightReelDlg->setModal(false);
hilightReelDlg->show();
}
ui->btnShare->setEnabled(true);
}
Praveen Kumar
You can try create QDialog with null parent insead of pointer to mainwindow. Is this case dialog will not block mainwindow. But I am sure you shouldn't do that, because in such case you will broke default behavior, which everybody used to use.

Qt - QStackedLayout setCurrentIndex displays blank window instead of widget

I just started learning Qt a couple days ago to make a game, and I'm trying to figure out how to make layouts work.
What I want is a Window using QStackedLayout with 2 widgets inside: StartScreen and GameScreen. StartScreen is shown on top on program run. A button in StartScren is connected to a function inside Window, and Window will call setCurrentIndex to change the widget on top to GameScreen.
What happens right now is that when I click on the button, the view changes to a blank window. I've tried hardcoding to setCurrentIndex(0), which does nothing, setCurrentIndex(1), which is what GameScreen should be and displays the same blank window, and setCurrentIndex(2), which is out of index bounds but still does nothing. So the connection is going through, but I don't understand why a blank window will show up instead of the button I have on GameScreen.
If someone can explain to me what concept I missed and how to fix it, I'd greatly appreciate it. Thanks!
Here is window.cpp:
Window::Window(QWidget *parent) : QWidget(parent)
{
resize(640, 480);
layout = new QStackedLayout;
createStartScreen();
createGameScreen();
setLayout(layout);
show();
};
void Window::createStartScreen(){
start = new StartScreen();
layout->addWidget(start);
start->setWindow(this);
}
void Window::playGame(){
layout->setCurrentIndex(layout->indexOf(game));
}
void Window::createGameScreen(){
game = new GameScreen();
layout->addWidget(game);
}
startscreen.cpp:
StartScreen::StartScreen(QWidget *parent) : QWidget(parent)
{
newGameButton = new QPushButton("New Game", this);
newGameButton->setGeometry(QRect(QPoint(260, 300), QSize(120,40)));
quitButton = new QPushButton("Quit", this);
quitButton->setGeometry(QRect(QPoint(260, 360), QSize(120,40)));
connect(quitButton, SIGNAL(clicked()), QApplication::instance(), SLOT(quit()));
};
void StartScreen::setWindow(Window *w){
connect(newGameButton, SIGNAL(clicked()), w, SLOT(playGame()));
}
gamescreen.cpp:
GameScreen::GameScreen(QWidget *parent) : QWidget(parent)
{
button = new QPushButton("Hi");
button->setGeometry(QRect(QPoint(260, 260), QSize(120,40)));
};
That's because you don't call show on button. But you should rather use a layout to handle it.
e.g.:
GameScreen::GameScreen(QWidget *parent)
: QWidget(parent)
{
button = new QPushButton(tr("Hi"));
QHBoxLayout *layout = new QHBoxLayout(this);
layout->addWidget(button);
};
button will have a size adapted to its text and will be cleaned positioned in GameScreen.
On a side note, you should rather add a signal to StartScreen to request a new game and do the connection in Window. That way you won't have a tight coupling between StartScreen and Window.

Qt: Resizing QMenuBar corner widget

I put a push button into the top-right corner of my main window menu bar:
QPushButton *pb = new QPushButton("Text");
pb->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
QMainWindow *mainWindow;
mainWindow->menuBar()->setCornerWidget(pb, Qt::TopRightCorner);
The initial layout is fine. Sometime later, an asynchronous event changes the QPushButton's text to a longer string, but it gets clipped on the right.
I can see that the QPushButton's size changes when the string is updated. The QPushButton is displayed correctly if the window is resized. The problem appears to be getting the QMenuBar to recognize that the widget's size has changed.
This answer How to auto change QPushButton width and QMenuBar corner widget width when change text of button? suggests resetting the corner widget. I would rather avoid that, because my application's structure makes me jump through several ugly and awkward hoops to reset the corner widget after initializing.
The solution is simple. After updating the text of the button call menuBar()->adjustSize(); I have tested it in Qt5.5 and hope it will work for you.
You can use QWidgetAction as a horizontal menu widget:
class TestMenu : public QWidgetAction
{
public:
TestMenu(QObject *parent) :
QWidgetAction (parent)
{
}
virtual QWidget *createWidget(QWidget *parent)
{
QComboBox *combo = new QComboBox(parent);
combo->setFixedWidth(300);
return combo;
}
virtual void deleteWidget(QWidget *widget)
{
delete widget;
}
};
...
QMenu *menu = new QMenu();
menu->addAction(new TestMenu(this));
menuBar()->setCornerWidget(menu);

QTabWidget how to hide pane only?

I have added a QToolButton as corner widget in QTabWidget which is checkable. I want to hide all tabs (panes only) when the tool button is unchecked. I tried to connect button's signal clicked(bool) with all tab's setVisible(bool) slot not working but. I also connected tabwidget's setvisible to the signal but complete widget became invisible(it was a silly trial). Is there any way to make only pane invisible and tab bar will not disappear ?
Edit: Code (ui have a tabwidget and two tabs namely tab and tab_2)
ui->setupUi(this);
QToolButton * b = new QToolButton;
b->setCheckable(true);
b->setChecked(true);
b->setAutoRaise(true);
b->setText("Hide Tabs");
ui->tabWidget->setCornerWidget(b);
connect(b,SIGNAL(clicked()),ui->tab,SLOT(hide()));
connect(b,SIGNAL(clicked()),ui->tab_2,SLOT(hide()));
Use qFindChild to find the QTabBar within the QTabWidget:
QTabBar *tabBar = qFindChild<QTabBar *>(ui->tabWidget);
tabBar->hide();
For Qt5:
QTabBar *tabBar = ui->tabWidget->findChild<QTabBar *>();
tabBar->hide();
so I understand it like this, you want to hide the TabBar and let the tab visible. Or at least that's what I get from your question
Well if that the case all you have to do it's this:
connect(ui->pushButton,SIGNAL(clicked()),ui->tabWidget->tabBar(),SLOT(hide()));
I hope this was helpful, even do the questions in a little old, I though it may help new viewers.
Here is my take on this. I've created a class that inherits QTabWidget. What I do is; set the "maximum vertical size of QTabWidget" to its tabBars height to hide the panels.
It is a hacky solution and I had to add some extra lines to deal with quirks.
file: hidabletabwidget.h
#ifndef HIDABLETABWIDGET_H
#define HIDABLETABWIDGET_H
#include <QTabWidget>
#include <QAction>
class HidableTabWidget : public QTabWidget
{
Q_OBJECT
public:
explicit HidableTabWidget(QWidget *parent = 0);
QAction hideAction;
private slots:
void onHideAction(bool checked);
void onTabBarClicked();
};
#endif // HIDABLETABWIDGET_H
file: hidablewidget.cpp
#include "hidabletabwidget.h"
#include <QTabBar>
#include <QToolButton>
HidableTabWidget::HidableTabWidget(QWidget *parent) :
QTabWidget(parent),
hideAction("▾", this)
{
hideAction.setCheckable(true);
hideAction.setToolTip("Hide Panels");
QToolButton* hideButton = new QToolButton();
hideButton->setDefaultAction(&hideAction);
hideButton->setAutoRaise(true);
this->setCornerWidget(hideButton);
connect(&hideAction, SIGNAL(toggled(bool)), this, SLOT(onHideAction(bool)));
connect(this, SIGNAL(tabBarClicked(int)), this, SLOT(onTabBarClicked()));
}
void HidableTabWidget::onHideAction(bool checked)
{
if (checked)
{
this->setMaximumHeight(this->tabBar()->height());
this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
}
else
{
this->setMaximumHeight(QWIDGETSIZE_MAX); // by default widgets can expand to a maximum sized defined by this macro
this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
}
}
void HidableTabWidget::onTabBarClicked()
{
hideAction.setChecked(false);
}
To use this, you can simply "promote" your QTabWidget to "HidableTabWidget" using qt designer.
And here is how it looks on my system:
You usually want to remove the Tab from the QTabWidget:
void QTabWidget::removeTab ( int index )
The Tab removed will not be deleted and can be reinserted!
So you would connect your QToolButton b to a slot which simply removes the Tabs like this:
connect( b, SIGNAL(clicked()), this, SLOT(hideTabs() );
..
void Foobar::hideTabs( void )
{
for( int i = 0; i < ui->tabWidget->count(); ++i )
ui->tabWidget->removeTab(i);
}
I can not comment due to my low "reputation" so far. If I could I'd just add a comment to Anatoli's answer: the goal is to hide "page area", not "tab bar". So if we imply they always use QStackedWidget for that then the answer should be more like:
auto * tab_pane = qFindChild<QStackedWidget *>(ui->tabWidget);
tab_pane->hide();
or for Qt5:
auto * tab_pane = ui->tabWidget->findChild<QStackedWidget *>();
tab_pane->hide();

Qt/win: showMaximized() overlapping taskbar on a frameless window

I'm building an Qt-Application without the default window border as a frameless window.
The window functions are included by setting window flags in the QMainWindow like:
MainDialog::MainDialog(QWidget *parent):
QMainWindow(parent), currentProject(NULL), currentUser(NULL),
aViews(new QList<AViewForm*>()),
bViews(new QList<BViewForm*>()),
cViews(new QList<CViewForm*>())
{
ui.setupUi(this);
this->statusBar()->showMessage(tr(""));
this->setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowSystemMenuHint);
...
}
The MainWindow has an .ui file within, thats why I cannot inherit from QDesktopWidget.
The Problem I have now is that the Appication overlays the windows taskbar when maximizing.
My Question now: is there any posibility to find out the available height of the OS desktop without the
availableGeometry().height()
-Method of QDesktopWidget? I cannot find anything in the documentation :(
Somebody else here asked a similar Question but used a QWidget instead of a QMainWindow.
I would be glad about any hints to my Problem
As you say you can use QDesktopWidget. If you don't have your class inherit from it you can create one in your constructor just for retrieving the height :
QDesktopWidget w;
int availableHeight = w.availableGeometry().height();
Guess thats not good practise, but i solved it as followed:
I built a new class which needs a MainWindow as param and with slots for the scaling actions:
FullScreen::FullScreen(QMainWindow &mainWindow, QObject *parent) : QObject(parent), mainWindow(mainWindow)
{
this->saveCurrentPosition();
}
void FullScreen::maximize()
{
this->saveCurrentPosition();
mainWindow.move(QApplication::desktop()->mapToGlobal(QApplication::desktop()->availableGeometry().topLeft()));
mainWindow.resize(QApplication::desktop()->availableGeometry().size());
}
void FullScreen::normalize()
{
mainWindow.move(lastGlobalPosition);
mainWindow.resize(lastSize);
}
void FullScreen::saveCurrentPosition()
{
lastGlobalPosition = mainWindow.mapToGlobal(mainWindow.rect().topLeft());
lastSize = mainWindow.size();
}
The only Problem which now occures is when the application is fullscreen and you move the taskbar. I have not set any resizeEvent though

Resources