Qt - Change application title dynamically on macOS [duplicate] - c++

This question already has an answer here:
How to rename the program-name menu-label in a MacOS/X program?
(1 answer)
Closed 1 year ago.
I want to change the title of my Qt 5.15.0 application after it was executed.
For doing that, I'm using the setWindowTitle function of the QWidget class, like so:
setWindowTitle("My new window title");
Turns out the title is changed correctly on Windows but not on macOS. Here are the results:
Windows 10
macOS Catalina
You can see that in macOS the title is updated in the Window but not in the MenuBar (top) and in the Dock (bottom).
Is there a way to change all the titles on macOS once the app is running?
Edit
I managed to change the MenuBar title using the Objective-C code posted in this question (I just had to rename my .cpp file to .mm):
#import <AppKit/NSApplication.h>
#import <AppKit/NSMenu.h>
void setMenuProgramName(const char* newName)
{
NSMenu* mainMenu = [[NSApplication sharedApplication] mainMenu];
NSMenu* appMenu = [[mainMenu itemAtIndex:0] submenu];
[appMenu setTitle:[[NSString alloc] initWithUTF8String:newName]];
}
There's still the problem with changing the name in the Dock. There are some insights here and here but I couldn't make it work yet. It is said that I should "comment out NSApplicationMain in supporting files -> main.m" but I don't have that file and I don't know how could I do that using Qt. That's why I propose that the question be reopened since there's no solution for that yet.
Edit II
Apparently, as mentioned in this response, there's no way to change the title when you hover over the app icon in the Dock.
Alternatively, you can add a "badge" with the following code, but that's meant for notifications.
[[NSApp dockTile] setBadgeLabel:#"My custom text"]
It would be nice to know why this can't be changed - if it's because of a bad design decision or just a poorly developed framework.

you can like this:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
QString windowTitle("New Title");
this->setWindowTitle(windowTitle);
}

Related

How to add "status bar" to QT widget - without using QTDesigner

I am creating QT QEditText widget (C++) dynamically at run time.
I cannot use "static ways" AKA QTDesigner to add / design the widget - it is NOT a form.
I know "status bar" is used as default in "MainWindow".
I want to add same functions in QTextEdit.
The QT doc has an example of C++ code on how to use "status bar" in MainWindow - that is of little help.
I have added this code to the QTextEdit constructor
childStatusBar = new QStatusBar();
childStatusBar->setStatusTip(" Show current copy drag and drop text");
childStatusBar->showNormal();
childStatusBar->showMessage("Status test message");
It compiles and runs, but there is no "status bar".
I do not know what is missing in my code and would
appreciate an assistance in solving this issue.
(Links , references to code examples would be helpful)
Please make sure to
read the post
and replay with facts, not opinions.
Suggestion for alternates are NOT solutions.
Please avoid any format of "ask your friend", RTFM.
Been there, done that.
As far as Mt Higgins is concerned, I am not asking for editing my post - I am not
posting to get a lecture in English grammar or composition.
Cheers and
"... thanks for watching..."
Just create a Qt MainWindow or Widget example and create a statusbar on it. Build the project and you can find your ui_...h in your build directory. Open it and find the QStatusBar widget. You can copy from there.
Note: Layouts are very important in Qt. So don't forget main-widget / main-window main layout and it's relation with statusbar. And also statusbar's layout.
As we can see in QStatusBar document :
Typically, a request for the status bar functionality occurs in
relation to a QMainWindow object. QMainWindow provides a main
application window, with a menu bar, toolbars, dock widgets and a
status bar around a large central widget
So you need something like this code:
#include <QApplication>
#include <QMainWindow>
#include <QStatusBar>
#include <QTextEdit>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMainWindow *w = new QMainWindow();
w->resize(600, 400);
QTextEdit *textEdit = new QTextEdit(w);
textEdit->setStatusTip("Show current copy drag and drop text");
auto childStatusBar = new QStatusBar(w);
childStatusBar->showMessage("Status test message");
w->setStatusBar(childStatusBar);
w->setCentralWidget(textEdit);
w->show();
return a.exec();
}
and also QTextEdit has a setStatusTip function that you can add "Show current copy drag and drop text" there instead of childStatusBar.
NOTED: As I mentioned ‍QTextEdit‍ cannot have ‍QStatusBar as you use in your code.
Now, if you don't want to use this method(use QMainWindow ), you have to create a custom and personalized class for yourself.
This means that you have to write the StatusBar by yourself

Clicking QSystemTrayIcon brings up an empty context menu on Mate desktop

I'd like to create a tray icon for my application for showing the main window on clicking on it after the former was minimized.
Here's the implementation:
TrayIcon.h:
class TrayIcon_t : public QSystemTrayIcon {
Q_OBJECT
public:
TrayIcon_t();
};
TrayIcon.cpp:
TrayIcon_t::TrayIcon_t() {
setIcon(QIcon(":/icons/tray.ico"));
}
Main.cpp (part only, there's no more code related to the tray):
TrayIcon_t *tray = new TrayIcon_t;
QObject::connect(tray, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), &MainWindow, SLOT(show()));
tray->show();
While on LXDE it works just fine, on MATE desktop it mostly opens a small menu (I think) containing no items and doesn't emit the signal required by the main window to be shown. See this picture.
Do you think I've encountered a bug in Qt 5.7.0?
Turns out that this is a bug. Reported it and became accepted at:
https://bugreports.qt.io/browse/QTBUG-55717

Set alignment of QGroupBox title

I try programmatically set alignment of title of QGroupBox. According to the documentation I try to do it in the following way:
MainWidget::MainWidget (QWidget * parent)
: QWidget (parent)
{
setWindowTitle (tr ("QGropBox Title Alignment issue") );
QGroupBox * group = new QGroupBox ("Group Title", this);
QVBoxLayout * layoutTop = new QVBoxLayout ();
layoutTop->addWidget (group);
group->setAlignment (Qt::AlignHCenter);
this->setLayout (layoutTop);
}
But I have got unexpected result and title aligned with the left-hand side of the group box.
Such behaviour I have got with the environment:
Debian 9.0 (sid);
Qt 5.5.1 (installed from repository);
XMonad DE.
The same behaviour I have got with the next environment:
Ubuntu 15.10;
Qt 5.4 (installed manually using offline-installer);
KDE.
But! If I use Qt installed from repository (Qt 5.4.2) the title will aligned with the centre by default. But if I change align to the left it will not changed.
I try find some solution with Google, but I haven't found similar questions and this is bad sign and usually this is means that I do some thing wrong.
So my question is: Why I can't manage by alignment of the group box title.
It seems like in Qt 5.5.1 there is a bug for some visual styles when QGroupBox title alignment is not taken into account when title's rect is computed: QTBUG-49068: QGroupBox title does not follow alignment with fusion style.
You can download most recent version from git repository, build it and check if the bug has been fixed (is has been for Fusion style: qt commit 139953).
If bug still occurs, I think you should submit an issue to Qt bugtracker.

Programming with Qt creator and Cocoa ( copying the selected text from the current application)

I would like to know if there is a way to use the Cocoa API in a Qt application.
I've already used the Windows API to get the selected text from the active application.
I'd like to do the same with mac os.
I tried to make a simple "hello world" application C++ with xCode, including the <Cocoa/Cocoa.h> but it didn't work as I excepted.
Is there a way to get this "hello word" application to build with Cocoa?
And, also If that is possible, can I get the selected text from the active windows with Cocoa API?
EDIT :
All right, so I successfully build something using Cocoa.h, thanks to this thread : How to mix Qt, C++ and Obj-C/Cocoa.
For the selection problem you could check out the answers I posted which tell you how to do it.
For those who could be interested : I found a way to get the current selected text.
Just by simulating cmd + c :
So thanks to this thread, I changed the code to obtain the "c" key which is represented by the integer 8 (Found in NSEvent.h), so here's the code :
CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
CGEventRef saveCommandDown = CGEventCreateKeyboardEvent(source, (CGKeyCode)8, YES);
CGEventSetFlags(saveCommandDown, kCGEventFlagMaskCommand);
CGEventRef saveCommandUp = CGEventCreateKeyboardEvent(source, (CGKeyCode)8, NO);
CGEventPost(kCGAnnotatedSessionEventTap, saveCommandDown);
CGEventPost(kCGAnnotatedSessionEventTap, saveCommandUp);
CFRelease(saveCommandUp);
CFRelease(saveCommandDown);
CFRelease(source);
Now you just have to access the clipboard from Qt to get the selection. (If ask, I can put the code to do so)
Anyway, thanks to the stackoverflow community ;)

setCentralWidget() causing the QMainWindow to crash.. Why?

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
this->setupUi(this);
this->setupActions();
this->setWindowTitle(tr("CuteEdit"));
label = new QLabel(tr("No Open Files"));
this->setCentralWidget(label);
label->setAlignment(Qt::AlignCenter);
}
By above code, I get a GUI like this(Its a screenshot of whole screen, Only observe the window displayed in middle of page of ebook). (I used QT Designer)
Now, i want user to select File->Open.. A Dialog appears and file gets selected.. Its contents are to be displayed in *textEdit widget..
Function for that is below..
void MainWindow::loadFile()
{
QString filename = QFileDialog::getOpenFileName(this);
QFile file(filename);
if (file.open(QIODevice::ReadOnly|QIODevice::Text))
{
label->hide();
textEdit->setPlainText(file.readAll());
mFilePath = filename;
QMainWindow::statusBar()->showMessage(tr("File successfully loaded."), 3000);
}
}
The window crashes at line:-
textEdit->setPlainText(file.readAll());
But if i comment the line:-
this->setCentralWidget(label);
i mean i remove label as being the central widget, the program runs as expected.. Why?
And also, I am not clear about the concept of CentralWidget. Pls guide.
JimDaniel is right in his last edit. Take a look at the source code of setCentralWidget():
void QMainWindow::setCentralWidget(QWidget *widget)
{
Q_D(QMainWindow);
if (d->layout->centralWidget() && d->layout->centralWidget() != widget) {
d->layout->centralWidget()->hide();
d->layout->centralWidget()->deleteLater();
}
d->layout->setCentralWidget(widget);
}
Do you see that if your MainWindow already had centralWidget() Qt schedules this object for deletion by deleteLater()?
And centralWidget() is the root widget for all layouts and other widgets in QMainWindow. Not the widget which is centered on window. So each QMainWindow produced by master in Qt Creator already has this root widget. (Take a look at your ui_mainwindow.h as JimDaniel proposed and you will see).
And you schedule this root widget for deletion in your window constructor! Nonsense! =)
I think for you it's a good idea to start new year by reading some book on Qt. =)
Happy New Year!
Are you sure it's not label->hide() that's crashing the app? Perhaps Qt doesn't like you hiding the central widget. I use Qt but I don't mess with QMainWindow that often.
EDIT: I compiled your code. I can help you a bit. Not sure what the ultimate reason is as I don't use the form generator, but you probably shouldn't be resetting the central widget to your label, as it's also set by the designer, if you open the ui_mainwindow.h file and look in setupGui() you can see that it has a widget called centralWidget that's already set. Since you have used the designer for your GUI, I would use it all the way and put the label widget in there as well. That will likely fix your problems. Maybe someone else can be of more help...
I'm not sure I understood your problem, neither what the guys above said (which I guess are valid information) and it seems to be an old topic.
However, I think I had a problem that looks like this and solved it, so I want to contribute my solution in case it helps anyone.
I was trying to "reset" central widget using QLabels. I had three different ones, switch from first to second, then to third and failed to switch back to the first one.
This is my solution that worked:
Header file
QLabel *imageLabel;
Constructor
imageLabel = new QLabel("<img src='/folder/etc.jpg' />");
this->setCentralWidget(imageLabel);
Reset
imageLabel = NULL;
imageLabel = new QLabel("<img src='/folder/etc.jpg' />");
this->setCentralWidget(imageLabel);
Hope that helps
Aris