PDA

View Full Version : Layouts and Window sizes problem



PstdEr
28th October 2013, 19:56
I am creating an application which has some widgets like display window , keypad and log window.

display window to display some external application
keypad to control application
log window to display logs

the difficulty i am facing is with layouts and window sizes
i want to see my interface look same way in minimized and maximized state , i mean
all borders of windows.

Images are attached.

Problem 1:
when in minimized state
At the right most side(between DispWin and KeyWin) and at the bottom just above the LogWin(between LogWin and DispWin), i cannot see border of MainWin(i.e Cyan color)

Problem 2:
when in maxiimized state and in minimized state
The keypad height is exceding the height of MainWin despite setting proper height.

I want to see all the borders of windows( ie Cyan color around DispWin, LogWin and NavyBlue around MainWin and KeyWin.

I tried in various ways , but could not achieve.

please help...



#define KEYPAD_WIDTH 200
#define KEYPAD_HEIGHT 700

#define LOGWINDOW_HEIGHT 80

#define MIN_WIDTH_FACTOR 240
#define MIN_HEIGHT_FACTOR 100

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
int x_c, y_c, screen_width,screen_height;
int display_window_width,display_window_height;


ServerWin = new QWidget;
MainWin = new QWidget;
DispWin = new QWidget;
LogWin = new QWidget;
KeyWin = new QWidget;

QHBoxLayout *Mlayout = new QHBoxLayout;
QVBoxLayout *Dlayout = new QVBoxLayout;

QDesktopWidget *D = new QDesktopWidget;
QRect rect = D->geometry();
rect.getRect(&x_c,&y_c,&screen_width,&screen_height);
qDebug()<<"x="<<x_c<<"y="<<y_c<<"s_w="<<screen_width<<"s_h="<<screen_height<<endl;
display_window_width = screen_width - MIN_WIDTH_FACTOR - KEYPAD_WIDTH;
display_window_height = screen_height- MIN_HEIGHT_FACTOR - LOGWINDOW_HEIGHT;


setMinimumSize(screen_width - MIN_WIDTH_FACTOR,screen_height-MIN_HEIGHT_FACTOR);
setMaximumSize(screen_width, screen_height);
//setSizePolicy(QSizePolicy::Expanding,QSizePolicy:: Expanding);

ServerWin->setMinimumSize(screen_width - MIN_WIDTH_FACTOR,screen_height-MIN_HEIGHT_FACTOR);
ServerWin->setMaximumSize(screen_width, screen_height);
setCentralWidget(ServerWin);
ServerWin->setSizePolicy(QSizePolicy::Expanding,QSizePolicy:: Expanding);
setPalette(QPalette(QColor(0,0,128,255)));//Navy Blue
setAutoFillBackground(true);


MainWin->setPalette(QPalette(QColor(0,255,255,255)));//Cyan
MainWin->setAutoFillBackground(true);

Dlayout->addWidget(DispWin);
DispWin->setPalette(QPalette(QColor( 230,230,250,255)));//Lavender
DispWin->setAutoFillBackground(true);
Dlayout->setSpacing(1);
DispWin->setMinimumSize(display_window_width,display_window _height);

Dlayout->addWidget(LogWin);
LogWin->setPalette(QPalette(QColor(148,0,211,255)));//Dark Violet
LogWin->setAutoFillBackground(true);
LogWin->setMinimumSize(display_window_width,LOGWINDOW_HEIG HT);

MainWin->setLayout(Dlayout);

KeyWin->setPalette(QPalette(QColor( 238,130,238,255)));//Violet
KeyWin->setAutoFillBackground(true);

//QWidget* keypad = new QWidget;
//QHBoxLayout *vLay = new QHBoxLayout;
//keypad->setLayout(vLay);

//KeyWin->setFixedSize(KEYPAD_WIDTH,KEYPAD_HEIGHT+20);
//KeyWin->setFixedSize(KEYPAD_WIDTH,(display_window_height+L OGWINDOW_HEIGHT/*+MIN_HEIGHT_FACTOR*/));
//KeyWin->setFixedSize(KEYPAD_WIDTH,display_window_height+LO GWINDOW_HEIGHT /*(screen_height-MIN_HEIGHT_FACTOR+display_window_height-100)*/);
KeyWin->setFixedSize(KEYPAD_WIDTH,DispWin->height()+LogWin->height() /*(screen_height-MIN_HEIGHT_FACTOR+display_window_height-100)*/);
//KeyWin->setMinimumSize(KEYPAD_WIDTH,(screen_height-MIN_HEIGHT_FACTOR));
//vLay->addWidget(KeyWin);
vLay->setContentsMargins(0,0,0,0);

Mlayout->addWidget(MainWin);
Mlayout->setSpacing(1);
Mlayout->addWidget(KeyWin);
ServerWin->setLayout(Mlayout);
}

PstdEr
29th October 2013, 05:17
I know , it may be difficult or rather boring to see this kind of post, but i have tried in various ways, yet could not get what i wanted.

I will explain in simple terms , so that i might get some reply.

what i want is to display all windows with the borders no matter they are in MinimumSize or MaximumSize.

the problem here is when it is in MinimumSize the windows DispWin, and LogWin are not completely seen, the KeyWin overlaps these two windows.
when Maximized every thing is seen with border.

I want the same look that shows in MinimumSize state even if the window is in MinimumSize, ofcourse the windows are small , but should be able to see full windows.

ChrisW67
29th October 2013, 07:17
Your code does nothing to make it clear what you are trying to do without someone spending a fair amount of time just decoding it, and that's after they get it to compile. Your simple terms don't really help. There are no "borders" in your code either as QFrame objects or QSS styles.

The "borders" you are complaining about appear to be the inter-widget gaps that show the underlying widget's colour. If child widgets are overlapping then that is a certain sign that something is wrong with the layouts; but I don't see overlapping widgets. I do see that you have set the inter widget spacing in both layouts to one pixel, which would easily explain not seeing the underlying widget through the gap. I see that you are trying to force the size of certain widgets, leaving the layout engine with no option but to do something awkward.

BTW: Your code uses vLay uninitialized. Your code leaks QDesktopWidget memory.

Here is my take on what you are trying to achieve.


MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
ServerWin = new QWidget(this);
ServerWin->setObjectName("ServerWin");
QRect geom = QApplication::desktop()->availableGeometry();
geom.adjust(0, 0, -MIN_WIDTH_FACTOR, -MIN_HEIGHT_FACTOR);
ServerWin->setMinimumSize(geom.size());

MainWin = new QWidget(this);
MainWin->setObjectName("MainWin");

DispWin = new QWidget(this);
DispWin->setObjectName("DispWin");

LogWin = new QWidget(this);
LogWin->setObjectName("LogWin");
LogWin->setMinimumHeight(LOGWINDOW_HEIGHT);
LogWin->setMaximumHeight(LOGWINDOW_HEIGHT);
LogWin->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);

KeyWin = new QWidget(this);
KeyWin->setObjectName("KeyWin");
KeyWin->setMinimumWidth(KEYPAD_WIDTH);
KeyWin->setMaximumWidth(KEYPAD_WIDTH);
KeyWin->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);


QVBoxLayout *vLayout = new QVBoxLayout(this);
vLayout->addWidget(DispWin);
vLayout->addWidget(LogWin);
MainWin->setLayout(vLayout);

QHBoxLayout *hLayout = new QHBoxLayout(this);
hLayout->addWidget(MainWin);
hLayout->addWidget(KeyWin);
ServerWin->setLayout(hLayout);

setCentralWidget(ServerWin);

setStyleSheet(
"#ServerWin { background: navy; }"
"#MainWin { background: cyan; }"
"#DispWin { background: lavender; }"
"#LogWin { background: darkviolet; }"
"#KeyWin { background: violet; }"
);
}

There are better ways to get a border on a lot of widgets (not bare QWidgets though).

anda_skoa
29th October 2013, 08:56
Btw, the desktop widget is usually acquired through QApplication::desktop()

Cheers,
_

PstdEr
29th October 2013, 10:11
Your code does nothing to make it clear what you are trying to do without someone spending a fair amount of time just decoding it, and that's after they get it to compile. Your simple terms don't really help. There are no "borders" in your code either as QFrame objects or QSS styles.
The "borders" you are complaining about appear to be the inter-widget gaps that show the underlying widget's colour.


Really sorry about that, i am not a frequent coder in Qt and dont know the basics.



BTW: Your code uses vLay uninitialized. Your code leaks QDesktopWidget memory.


Thanks for pointing, i could have used normal object instead of pointer :confused:

And thanks a lot, Its really beautiful after your changes are applied. :)

Added after 9 minutes:

I have a doubt here, is it the correct way of doing , because it gives a warning when running
" QLayout: Attempting to add QLayout "" to MainWindow "", which already has a layout "
this ( mainwindow) is already having a layout and we are again trying to set one more layout.



QVBoxLayout *vLayout = new QVBoxLayout(this);
QHBoxLayout *hLayout = new QHBoxLayout(this);

anda_skoa
29th October 2013, 13:37
Just create the layouts without parent.

Providing a parent is equivalent to calling parent->setLayout(), but QMainWindow already has a layout.

Cheers,
_

PstdEr
29th October 2013, 13:46
Sorry one more question, I dont have any where else to go :( .

I am using the following code to display external applications onto DispWin of previous application by passing its width and height.

The problem is after displaying the external app , if i maximize the window of main application , the external app does not resize to DispWin size, it stays same as when its displayed.

is there any thing i am doing wrong from below.

If you have time , please have a look ...



int create_window(int width, int height)
{
XSetWindowAttributes xswa;
static int resx, resy;
mDisplay = XOpenDisplay(NULL);
if(mDisplay == NULL){
printf("m_Display Failed");
return 0;
}
mScreen = DefaultScreen(mDisplay);

xswa.background_pixel=BlackPixel(mDisplay, mScreen);
xswa.border_pixel=WhitePixel(mDisplay, mScreen);
xswa.event_mask=ExposureMask|KeyPressMask|KeyRelea seMask|ButtonPressMask|ButtonReleaseMask|Structure NotifyMask;
xswa.override_redirect = False;

mRootWin = DefaultRootWindow(mDisplay);
if (!(window = XCreateWindow(mDisplay, mRootWin, 0, 0, width, height, 0, 0, InputOutput, DefaultVisual(mDisplay, mScreen),
CWEventMask|CWBackPixel|CWBorderPixel|CWOverrideRe direct, &xswa)))
{
fprintf(stderr, "[x11] Failed to create window\n");
return 0;
}
XMapWindow(mDisplay, window);
while (1)
{
XEvent event;
XNextEvent(mDisplay, &event);
if (event.type==Expose)
break;
}

{
XSizeHints SizeHints;
SizeHints.flags=PMinSize|PMaxSize|USSize;
SizeHints.min_width = width;// does not have any effect
SizeHints.min_height = height ;// does not have any effect
SizeHints.max_width= width;
SizeHints.max_height= height;
XSetWMNormalHints(mDisplay, window, &SizeHints);
}

return 1;
}





#define DEFAULT_SCENE_WIDTH 1280
#define DEFAULT_SCENE_HEIGHT 720

int main(int argc, char **argv)
{

int width;
int height;
int retVal =0;
qDebug()<<"argc"<<argc;
for(int i= 0;i<argc;i++)
qDebug()<<"argv["<<i<<"]= "<<argv[i];

QRectF sceneRect(0,0,DEFAULT_SCENE_WIDTH,DEFAULT_SCENE_HE IGHT);

QApplication app(argc, argv);
QGraphicsScene scene;

scene.setSceneRect(sceneRect);

QGraphicsView *gView = new QGraphicsView(&scene);

QWebView *wView = new QWebView();
wView->load(QUrl("http://127.0.0.1/setting.html"));
wView->grabKeyboard();

WId wid;
if(argc < 2)
{
printf("pass window arg\n");
return 0;
}
wid = app.arguments()[1].toInt();
embed = new QWidget();
QVBoxLayout* vl = new QVBoxLayout();
embed->setLayout(vl);
vl->addWidget(wView);
embed->show();

width = app.arguments()[2].toInt();
height = app.arguments()[3].toInt();
embed->setMinimumSize(width,height);
embed->setSizePolicy(QSizePolicy::Preferred,QSizePolicy:: Preferred);

qDebug()<<"width & height received:"<<width<<"&"<<height;

retVal = create_window(width,height);
if (0==retVal){
qDebug()<<"create_window failed";
return 0;
}

XReparentWindow(mDisplay,embed->winId(),window,0,0);
XReparentWindow(mDisplay,window,wid,0,0);
XFlush(mDisplay);
app.exec();
}