I am trying to open a new dialog Window from a existing dialog on a a button click event,but I am not able to do this as i opened the dialog window from MainWindow.
I am trying with:
Dialog1 *New = new Dialog1();
New->show();
Is there a different way of opening dialog window form existing dialog Window???
There must be some other problem, because your code looks good to me. Here's how I'd do it:
#include <QtGui>
class Dialog : public QDialog
{
public:
Dialog()
{
QDialog *subDialog = new QDialog;
subDialog->setWindowTitle("Sub Dialog");
QPushButton *button = new QPushButton("Push to open new dialog", this);
connect(button, SIGNAL(clicked()), subDialog, SLOT(show()));
}
};
class MainWindow : public QMainWindow
{
public:
MainWindow()
{
Dialog *dialog = new Dialog;
dialog->setWindowTitle("Dialog");
dialog->show();
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.setWindowTitle("Main Window");
w.show();
return a.exec();
}
By the way, note how I've connected QPushButton's "clicked" signal to QDialog's "show" slot. Very handy.
I am new to QT and I did have a similar problem. In my case, I was calling the new dialog from a function from the main dialog. I was using dlg->show which does not wait until the result of the new dialog. Hence the program still running. I change dlg->show for dlg->exec and the dialog works now. In your code, the dialog seems to be a local variable, perhaps you have the same problem. Other option could be to use a static pointer instead.
Dialog1 *newDlg = new Dialog1();
this->hide();
int result = newDlg->exec();
this->show();
delete newDlg;
in mainwindow.h file you should declare a pointer to your new dialog
and include the new dialog.h like
#include <myNewDialog.h>
private:
Ui::MainWindow *ui;
MyNewDialog *objMyNewDialog;
and after that you can call your dialog to be shown up in mainwindow.cpp
like
void MainWindow::on_btnClose_clicked()
{
objMyNewDialog= new MyNewDialog(this);
objMyNewDialog->show();
}
Related
I have a QTextEdit widget in a private slot, which I update regularly with setText() and insertPlainText().
I have found that setText()/insertPlainText() does not update the QTextEdit widget immediately. Instead, the QTextWidget is updated when the slot function returns. To test this, I have put a sleep() just after the setText()/insertPlainText().
class MyWindow : public Widget
{
MyWindow()
{
my_button = new QPushButton(this);
my_edit = new QTextEdit(this);
connect(my_button,
&QPushButton::clicked,
this,
&MyWindow::my_callback);
}
private slots:
void my_callback()
{
my_edit->setText("sample text");
// nothing happens; the QTextEdit
// widget does not show "sample text"
sleep(10);
// the QTextEdit widget will show
// "sample text" AFTER the sleep,
// when my_callback returns.
}
private:
QPushButton* my_button;
QTextEdit* my_edit;
}
This is a problem for me because I need to print a message in my QTextEdit widget BEFORE launching a time-consuming process (using QProcess). Currently, this message is not being printed until after QProcess process has returned.
Does anyone know how I can get the QTextEdit widget to show its contents right after setText()/insertPlainText()?
Using Qt5 on Fedora 29.
Never execute a task that consumes a lot of time in the GUI thread. In general, the solution is to execute that task in another thread, but in your case it indicates that you use QProcess, so I assume that you are using one of the methods waitForFinished(), waitForStarted() or waitForReadyRead(), instead you should use the signals:
#include <QtWidgets>
class Widget: public QWidget{
Q_OBJECT
public:
Widget(QWidget *parent=nullptr):
QWidget(parent)
{
button.setText("Press me");
QVBoxLayout *lay = new QVBoxLayout{this};
lay->addWidget(&button);
lay->addWidget(&textedit);
connect(&button, &QPushButton::clicked, this, &Widget::onClicked);
connect(&process, &QProcess::readyReadStandardError, this, &Widget::onReadyReadStandardError);
connect(&process, &QProcess::readyReadStandardOutput, this, &Widget::onReadAllStandardOutput);
}
private Q_SLOTS:
void onClicked(){
textedit.setText("sample text");
process.start("ping 8.8.8.8");
}
void onReadyReadStandardError(){
textedit.append(process.readAllStandardError());
}
void onReadAllStandardOutput(){
textedit.append(process.readAllStandardOutput());
}
private:
QPushButton button;
QTextEdit textedit;
QProcess process;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
#include "main.moc"
I wonder if calling
QCoreApplication::processEvents()
right after the ->setText("sample text") would do the trick in your case.
Here is some idea of my code.It executes successfully. I am just not able to use close button the moment it starts executing read statement.!
inside main():
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow mainWindow;
mainWindow.show();
return app.exec();
}
this is my constructor: one main window and a button that calls execute when clicked
inside MainWindow.cpp:
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent) //this creates a window that has a download button
{
setWindowTitle("File Downloader");
QWidget* central = new QWidget(this);
QVBoxLayout *lay = new QVBoxLayout(central);
button1 = new QPushButton("Download", this);
connect(button1, SIGNAL (clicked()),this,SLOT( execute()));
lay->addWidget(button1);
manager = new QNetworkAccessManager(this);
}
this function sets up connection with php file and then calls sendFinished
void MainWindow::execute() //PHP file link here
{
QUrl url"/patofmyphp");
reply = manager->post(request, data); //data is some string
connect(reply, SIGNAL (finished()),this,SLOT( sendFinished()));
}
this function reads data from php file in chunks
void MainWindow::sendFinished() //this gets called successfully
{
while(copied < size) //copied = 0, size = 10000;
{
const QByteArray data = reply->read(tocopy);
file.write(data);
copied += data.size();
}
}
Whole program is running successfully. But when I want to abort my reply using closebutton of QMainWindow before program gets executed successfully. But the moment it reply->read gets executed, it seems close button stops working. What should I do?
Looks like I solved my issue just by using this line inside my while loop.
QApplication::processEvents(); if(close == true) { closeProgram(); }
(Update on 2019-01-02: Simplify my example)
I am working on a program that can minimize to tray and hide the main window. I expect the mainwindow to show when I click on the tray icon. This usually works, but I find that if the program minimizes to tray when I call QFileDialog::getOpenFileName() to select file without closing the dialog, I cannot activate the trayicon. Does anyone know how to solve it? I am using Qt 5.12.0 (was using Qt 5.9.0) on Manjaro Linux.
Minimal, Complete, and Verifiable example:
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h:
class MainWindow : public QMainWindow
{
Q_OBJECT
QSystemTrayIcon *trayIcon;
QMenu *trayContextMenu;
QAction *actShow;
QPushButton *button;
public:
MainWindow(QWidget *parent = 0);
protected:
void changeEvent(QEvent *);
private slots:
void click();
void trayIcon_activated(QSystemTrayIcon::ActivationReason reason);
void actShow_Triggered();
};
#endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h"
#include <QFileDialog>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
QPushButton *button = new QPushButton("button", this);
setCentralWidget(button);
connect(button,&QPushButton::clicked,
this,&MainWindow::click);
trayIcon=new QSystemTrayIcon;
trayIcon->setIcon(QIcon("hmtimer.png"));
trayContextMenu=new QMenu;
actShow=trayContextMenu->addAction(tr("Show"));
trayIcon->setContextMenu(trayContextMenu);
connect(actShow,&QAction::triggered,
this,&MainWindow::actShow_Triggered);
connect(trayIcon,&QSystemTrayIcon::activated,
this,&MainWindow::trayIcon_activated);
}
void MainWindow::changeEvent(QEvent *event)
{
if(event->type()==QEvent::WindowStateChange){
if(isMinimized()){
this->hide();
trayIcon->show();
}
}
else{
QMainWindow::changeEvent(event);
}
}
void MainWindow::click()
{
QFileDialog::getOpenFileName(this,QString());
}
void MainWindow::trayIcon_activated(QSystemTrayIcon::ActivationReason reason)
{
if(reason==3){ //reason==Trigger
this->show();
trayIcon->hide();
}
}
void MainWindow::actShow_Triggered()
{
this->show();
trayIcon->hide();
}
The example can be downloaded here
It seems that if the program minimizes to tray when QFileDialog::getOpenFileName(this,QString()) is not closed, I cannot make the mainwindow appear by click on the tray icon or right click to show the context menu.
How to reproduce:
Open the program
Click on the button to open file dialog
Minimize to tray
Try clicking and right-clicking on the tray icon
I found a way to show the main window. I can do this by double clicking the icon with the following code of MainWindow::trayIcon_activated:
void MainWindow::trayIcon_activated(QSystemTrayIcon::ActivationReason reason)
{
if(reason==QSystemTrayIcon::DoubleClick){
this->show();
trayIcon->hide();
}
}
I still don't know how to show the mainwindow with single click or show the context menu with right click. If anyone knows, please tell me.
EDIT: Seems that this no longer works. I tried both my previous example and new example. Don't know what is going wrong.
/EDIT: solved, see my comment in the 1st answer!/
I am currently building an application which only has a tray icon displayed, so it doesn't have any windows.
Well, in the tray icon I've included a QAction so as to close the application. The thing is, that I get seg fault when I call exit(0); from that function. This is some example code:
//I have a reason for setting it to be a QTimer, please don't even comment on this
class Boot_Timer : public QTimer {
Q_OBJECT
public:
explicit Boot_Timer(QObject *parent = 0) : QTimer(parent) {
}
public Q_SLOTS:
void set_up_command_line_tray(){
//Setting up the tray Icon.
QSystemTrayIcon *trayIcon_cmd = new QSystemTrayIcon(this);
trayIcon_cmd->setIcon(QIcon(":/icons/Pictures/myapp.png"));
trayIcon_cmd->setToolTip("My tray tooltipp");
QMenu *changer_menu = new QMenu;
QAction *Quit_action = new QAction(tr("&Quit"), this);
Quit_action->setIconVisibleInMenu(true);;
connect(Quit_action, SIGNAL(triggered()), this, SLOT(close_application()));
changer_menu->addAction(Quit_action);
trayIcon_cmd->setContextMenu(changer_menu);
trayIcon_cmd->show();
}
void close_application(){
//HERE I GET SEG FAULT
exit(0);
}
};
Boot_Timer boottimer;
#include "main.moc"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//making some checks (code omitted)
...
boottimer.set_up_command_line_tray()
return app.exec();
}
So, the tray icon is shown normally and perfectly, but when I choose to Quit the application using the menu I've added to the tray icon, I get a seg fault. I guess that I cannot quit the application using exit(int state) outside main() function and its functions that don't have a parent...
What is the correct way to quit my application, then?
Thanks in advance for any answers!
Try to call
qApp->quit(0);
instead of
exit(0);
Remember to #include <QApplication>.
Thanks, that didn't solve it. For some reason, the thing that solved it was to do the following: QSystemTrayIcon *trayIcon_cmd = new QSystemTrayIcon(0); instead of QSystemTrayIcon *trayIcon_cmd = new QSystemTrayIcon(this)
I'm adding a bunch of QActions to my main window's menus. These actions can also be triggered by the keyboard, and I want the shortcut to be visible in the menu, as usual, e.g.
-----------------
|Copy Ctrl+C|
-----------------
I can do this using QAction.setShortcut(). However, I don't want these QActions to be triggered by the shortcuts; I'm handling all keyboard input separately elsewhere.
Is this possible? Can I disable the shortcut in the QAction but still have the shortcut text (in this example Ctrl + C) in my menus?
EDIT: The way I ended up doing it is connecting to the menu's aboutToShow() and aboutToHide() events, and enabling/disabling the shortcuts so they are only active when the menu is shown. But I'd appreciate a cleaner solution...
You could inherit from QAction and override QAction::event(QEvent*):
class TriggerlessShortcutAction : public QAction
{
public:
...ctors...
protected:
virtual bool event(QEvent* e)
{
if (e->type() == QEvent::Shortcut)
return true;
else
return QAction::event(e);
}
};
This will cause any events of type QEvent::Shortcut sent to your actions to not trigger the 'triggered()' signals.
action.setText("Copy\tCtrl+C");
This will look like an action with a shortcut, but the shortcut is not actually installed.
Here is a full example:
#include <QtGui>
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QMainWindow win;
QMenu *menu = win.menuBar()->addMenu("Test");
// This action will show Ctrl+T but will not trigger when Ctrl+T is typed.
QAction *testAction = new QAction("Test\tCtrl+T", &win);
app.connect(testAction, SIGNAL(triggered(bool)), SLOT(quit()));
menu->addAction(testAction);
// This action will show Ctrl+K and will trigger when Ctrl+K is typed.
QAction *quitAction = new QAction("Quit", &win);
quitAction->setShortcut(Qt::ControlModifier + Qt::Key_K);
app.connect(quitAction, SIGNAL(triggered(bool)), SLOT(quit()));
menu->addAction(quitAction);
win.show();
return app.exec();
}