Trolltech Home | Qt-jambi-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 1

Qt-jambi-interest Archive, November 2007
Issue with font size in Widget


Message 1 in thread

Hello,

First of all thanks to TT to have permitted Java prog the use of the 
wonderfull QT :)

Here is my issue. I have mixed some QT Jambi with swing (a former app 
I "translate" from swing to QTJambi screen by screen).
From a swing JFrame, when I click on a swing button, my app open a QTJambi 
QDialog.
All work correctly.
Then I close the QDialog (using the classical : 
lscreen.exit.clicked.connect(this, "close()");) and then if I try to open a 
new time my QDialog all is correct except the font size of all Widget who are 
biggest !

Here is the way I launch my QDialog :

	    if ("GO".equals(e.getActionCommand())) {
			String[] args = {"",""};
			QApplication.initialize(args);
			MyScreen diagAnniv = new MyScreen();
			diagAnniv.show();
			QApplication.exec();
	    }

This is not a big problem because I can use a screen with big size fonts, but 
I would like to understand.
Thanks for your help.


Message 2 in thread

paul wrote:
> Hello,
> 
> First of all thanks to TT to have permitted Java prog the use of the 
> wonderfull QT :)
> 
> Here is my issue. I have mixed some QT Jambi with swing (a former app 
> I "translate" from swing to QTJambi screen by screen).
> From a swing JFrame, when I click on a swing button, my app open a QTJambi 
> QDialog.
> All work correctly.
> Then I close the QDialog (using the classical : 
> lscreen.exit.clicked.connect(this, "close()");) and then if I try to open a 
> new time my QDialog all is correct except the font size of all Widget who are 
> biggest !
> 
> Here is the way I launch my QDialog :
> 
> 	    if ("GO".equals(e.getActionCommand())) {
> 			String[] args = {"",""};
> 			QApplication.initialize(args);
> 			MyScreen diagAnniv = new MyScreen();
> 			diagAnniv.show();
> 			QApplication.exec();
> 	    }
> 
> This is not a big problem because I can use a screen with big size fonts, but 
> I would like to understand.
> Thanks for your help.

Hi Paul,

There are a few things I immediatly see in your code that are wrong. 
First  is that QApplication can and should only be initialized once. 
This should give an exception, but because you call exec() on it it will 
reset the internal pointer. We will probably add an runtime exception to 
catch this kind of error for a future release. My guess is that the font 
issue is a side effect of that you're doing an illegal thing with 
QApplication, namely initializing twice.

The second problem is that Swing you are executing this code on the 
Swing Event thread, which is not favorable... On Linux and Windows, I 
believe this will "just work", but there might be side effects... There 
is also the case that you cannot do exec(), e.g. process Qt events, as 
this blocks the swing event loop. On Mac OS X, you will get an error if 
QApplication is not started on the first thread.

Another issue might be intended, but still, QDialogs should be shown 
using exec() rather than show(). The reason for this is that exec() will 
properly nest the event loop and preserve modality. If you don't use 
modal dialogs, it is less of a problem.

The last problem here is that Qt applications automatically shut down 
when you close the last window. This is a convenience feature, which you 
in your scenario don't want. You want QApplication.exec to run "forever" 
and never exit. To acheive this you need to set 
QApplication.setQuitOnLastWindowClosed(false);

I've attached an example where I illustrate the more proper way of 
acheiving this.

In main() I initialize QApplication and later call exec(), tying 
QApplication and all Qt Jambi related execution to the process' main 
thread. In my JButton event handler, which is called from the AWT event 
dispacth thread, I synchronize on QApplication.instance() (any instance 
would do, this was just a conveniently available one), pass the code I 
want executed to QApplication and wait().

The QApplication event loop will pick up my invoked later ExecuteQt 
runnable and execute it in the correct thread. This also synchronizes on 
QApplication.instance(). It then performs its tasks and calls 
QDialog.exec(). Once its done, it passes execution back to the Swing 
thread using QApplication.instance().notify().

This example runs again and again, with the correct fonts every time.

Hope this help your porting efforts

best regards,
Gunnar
import java.awt.event.*;
import java.awt.event.*;
import javax.swing.*;

import com.trolltech.qt.gui.*;

public class QDialogInSwing {

    private static class ExecuteQt implements Runnable {
        public void run() {
            System.out.println("jambi: running \"later\"");
            synchronized(QApplication.instance()) {
                System.out.println("jambi: actual execution");
                QDialog d = new QDialog();
                QPushButton button = new QPushButton("Qt Button");
                button.clicked.connect(d, "accept()");

                QVBoxLayout layout = new QVBoxLayout(d);
                layout.addWidget(button);

                System.out.println("jambi: modal dialog launching...");
                d.exec();

                System.out.println("jambi: done... waking up swint thread...");
                QApplication.instance().notify();
            }
        }

    }

    private static class LaunchQtFromSwingHandler implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            synchronized(QApplication.instance()) {
                System.out.println("swing: calling invoke later...\n");
                QApplication.invokeLater(new ExecuteQt());
                System.out.println("swing: waiting...\n");
                try {
                    QApplication.instance().wait();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                System.out.println("swing: done waiting...\n");
            }
        }
    }

    public static void main(String args[]) {

        QApplication.initialize(args);

        QApplication.setQuitOnLastWindowClosed(false);

        JFrame f = new JFrame();
        JButton b = new JButton("SwingButton");
        f.getContentPane().add(b);
        f.pack();
        f.setVisible(true);

        b.addActionListener(new LaunchQtFromSwingHandler());


        QApplication.exec();
    }

}

Message 3 in thread

Hi Gunnar,

You are great and your sample very usefull.
It's the fact I had to use a thread to launch my QDialog, run by 
QApplication.invokeLater(). Doing this way has permitted to initialize the 
QApplication only once in my main and solved my font issue.

Everything works now. It only remains for me to change all my swing screens...

Thanks a lot.
Paul.

Le Monday 26 November 2007 09:21:35, vous avez ÃcritÂ:
> private static class ExecuteQt implements Runnable {
> Â Â Â Â public void run() {
> Â Â Â Â Â Â System.out.println("jambi: running \"later\"");
> Â Â Â Â Â Â synchronized(QApplication.instance()) {
> Â Â Â Â Â Â Â Â System.out.println("jambi: actual execution");
> Â Â Â Â Â Â Â Â QDialog d = new QDialog();
> Â Â Â Â Â Â Â Â QPushButton button = new QPushButton("Qt Button");
> Â Â Â Â Â Â Â Â button.clicked.connect(d, "accept()");
>
> Â Â Â Â Â Â Â Â QVBoxLayout layout = new QVBoxLayout(d);
> Â Â Â Â Â Â Â Â layout.addWidget(button);
>
> Â Â Â Â Â Â Â Â System.out.println("jambi: modal dialog launching...");
> Â Â Â Â Â Â Â Â d.exec();
>
> Â Â Â Â Â Â Â Â System.out.println("jambi: done... waking up swint
> thread..."); QApplication.instance().notify();
> Â Â Â Â Â Â }
> Â Â Â Â }
>
> Â Â }