How to update a QTreeWidget by Clicking on QPushbutton - c++

I'm developing a Qt app in C++
I have create a layout with button bar, TreeView...
The Treeview is defined in my MainWindow.cpp
MainWindow::MainWindow()
{
setWindowTitle(QString::fromUtf8("PULS"));
resize(800,600);
setUnifiedTitleAndToolBarOnMac(true);
createDeviceStatusBar();
createSectionBar();
createTreeView();
QWidget *MainWindowWidget = new QWidget();
QVBoxLayout *MainWindowLayout = new QVBoxLayout(MainWindowWidget);
BrowserSection = new QGroupBox();
QWidget *BrowserWidget = new QWidget();
QHBoxLayout *BrowserLayout = new QHBoxLayout(BrowserWidget);
BrowserLayout->addWidget(SectionBar);
BrowserLayout->addWidget(TreeSection);
BrowserSection->setLayout(BrowserLayout);
MainWindowLayout->addWidget(DeviceSection);
MainWindowLayout->addWidget(BrowserSection);
setCentralWidget(MainWindowWidget);
show();
}
The createSectionBar() is a layout defined as below:
void MainWindow::createSectionBar()
{
SectionBar = new QGroupBox();
QVBoxLayout *SectionBarlayout = new QVBoxLayout;
SectionBarlayout->setContentsMargins(QMargins(0,0,0,0));
MusicButton = new QPushButton();
MusicButton->setFixedSize(110,150);
MusicButton->setIcon(QIcon(":/images/music.png"));
MusicButton->setIconSize(QSize(90,144));
MusicButton->setFlat(true);
MusicButton->setAutoFillBackground(true);
connect(MusicButton, SIGNAL(clicked()), this, SLOT(MusicTreeFile()));
SectionBarlayout->addWidget(MusicButton);
SectionBar->setLayout(SectionBarlayout);
}
The createTreeView() is defined as below to enable TreeView and Items.
void MainWindow::createTreeView()
{
TreeSection = new QGroupBox();
QVBoxLayout *TreeLayout = new QVBoxLayout;
MyTree = new TreeWidget();
MyTree->setSortingEnabled(true);
MyTree->setColumnWidth(0, 400);
QTreeWidgetItem* headerItem = new QTreeWidgetItem();
headerItem->setText(0,QString("File Name"));
headerItem->setText(1,QString("Size (Bytes)"));
headerItem->setText(2,QString("Date"));
MyTree->setHeaderItem(headerItem);
MyTree->setAutoFillBackground(true);
TreeLayout->addWidget(MyTree);
TreeSection->setLayout(TreeLayout);
}
What I need is to find a way to file the MyTree with
while (file != NULL && file->parent_id == folder_parent) {
QTreeWidgetItem* item = new QTreeWidgetItem();
int i;
LIBMTP_file_t *oldfile;
item->setText(0,file->filename);
Tree->addTopLevelItem(item);
....
}
here is the header file:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow();
protected:
private slots:
void MusicTreeFile();
private:
void createSectionBar();
void createTreeView();
void createDeviceStatusBar();
QGroupBox *SectionBar;
QGroupBox *TreeSection;
QGroupBox *DeviceSection;
QGroupBox *BrowserSection;
QPushButton *MusicButton;
TreeWidget *MyTree;
};
but it needs to be done only when clicking on MusicPushButton, I have already connected the MusicTreeFile() to the PushButton() action. but how to access to MyTree as it's also defined in another class..

You do not connect a signal to a class. You connect it to an instance of a class. And both of your instances are defined in MainWindow. So after both widgets are created you can call
QObject::connect(this->MusicButton, SIGNAL(clicked()), this->MyTree, SLOT(slot_name()));
With slot_name being your function
TreeWidget::slot_name{
while (file != NULL && file->parent_id == folder_parent) {
....
}
}

Related

Why Qt::AlignTop doesn't work in QVBoxLayout that I use like main layout?

I have simple class that inherits QDialog, I add dynamically elements
and my elements are located in the center, but I want to add them at the top.
class CustomDialog : public QDialog {
Q_OBJECT
private:
QVBoxLayout *mainLayout;
CustomDialog()
{
mainLayout = new QVBoxLayout();
setLayout(mainLayout);
}
public:
void update()
{
QLabel* label = new QLabel("some text");
QVBoxLayout *verLayout = new QVBoxLayout;
verLayout->addStretch();
verLayout->setAlignment(Qt::AlignTop);
verLayout->addWidget(label, Qt::AlignTop);
mainLayout->setAlignment(Qt::AlignTop);
mainLayout->addLayout(verLayout, Qt::AlignTop);
}
};
What am I doing wrong? and why my dynamically added elements always in center?
I understand that you want to place it and that the top is shown, so you could use QSpacerItem to push it.
class CustomDialog : public QDialog {
Q_OBJECT
QVBoxLayout *mainLayout;
public:
CustomDialog(QWidget *parent=0): QDialog(parent)
{
mainLayout = new QVBoxLayout(this);
QSpacerItem *verticalSpacer = new QSpacerItem(20, 217, QSizePolicy::Minimum, QSizePolicy::Expanding);
mainLayout->addItem(verticalSpacer);
addWidgets("1");
addWidgets("2");
}
private:
void addWidgets(const QString &text)
{
QLabel* label = new QLabel(text);
QVBoxLayout *verLayout = new QVBoxLayout;
verLayout->addStretch();
verLayout->setAlignment(Qt::AlignTop);
verLayout->addWidget(label, Qt::AlignTop);
mainLayout->setAlignment(Qt::AlignTop);
mainLayout->insertLayout(mainLayout->count()-1, verLayout);
}
};
Or if you want it to have a reverse order you must insert it in the first position with:
mainLayout->insertLayout(0, verLayout);
Note: The use of addLayout is incorrect since the second parameter is stretch.

qt 5.8 -> 5.9 logic_error

Recently updated from qt 5.8 to qt 5.9 and I'm getting some problems.
Pressing on a button that is not connected to any slot gives me:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_M_construct null not valid
Which is quite odd because before the update, it worked flawlessly. I'll paste some parts of the code so it will be a bit more clear.
First of all GUI is a class that inherits from QWidget.
#ifndef GUI_H
#define GUI_H
#include <QWidget>
#include <QHBoxLayout>
#include <QPushButton>
#include <QVBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QListWidget>
#include "Controller.h"
class GUI : public QWidget
{
Q_OBJECT
public:
GUI(Controller* ctrl);
void start();
~GUI();
private:
QLineEdit* txt_title;
QLineEdit* txt_desc;
QLineEdit* txt_type;
QLineEdit* txt_dur;
QPushButton* add_btn;
QPushButton* upd_btn;
QPushButton* rm_btn;
QPushButton* fil_desc_btn;
QPushButton* fil_type_btn;
QPushButton* fil_search_btn;
QPushButton* sort_title_btn;
QPushButton* sort_desc_btn;
QPushButton* sort_type_btn;
QPushButton* undo_btn;
QPushButton* refresh_btn;
QPushButton* shuffle_btn;
QListWidget* activities;
Controller* ctrl;
void setup_gui();
void connect_gui();
void add_to_list(Activity&);
void update_list();
public slots:
void add();
void edit();
void remove();
void search();
void undo();
void refresh_list();
void sort_title();
void sort_desc();
void sort_type();
void filter_desc();
void filter_type();
void shuffle();
};
#endif
And the methods that are relevant:
GUI::GUI(Controller* _ctrl)
{
this->ctrl = _ctrl;
this->setup_gui();
this->connect_gui();
setAttribute(Qt::WA_DeleteOnClose);
}
void GUI::add_to_list(Activity& activity)
{
string str = "";
str += activity.get_title() + "; " + activity.get_description() + "; " + activity.get_type() + "; " + std::to_string(activity.get_duration());
new QListWidgetItem(QString::fromStdString(str), this->activities);
}
void GUI::setup_gui()
{
this->setContentsMargins(10, 10, 10, 10);
QHBoxLayout* main_lay = new QHBoxLayout(this);
QVBoxLayout* left_lay = new QVBoxLayout();
QVBoxLayout* right_lay = new QVBoxLayout();
QHBoxLayout* title_lay = new QHBoxLayout();
QLabel* lbl_title = new QLabel(QObject::tr("title"));
lbl_title->setAlignment(Qt::AlignCenter);
this->txt_title = new QLineEdit();
QHBoxLayout* desc_lay = new QHBoxLayout();
QLabel* lbl_desc = new QLabel(QObject::tr("description"));
lbl_desc->setAlignment(Qt::AlignCenter);
this->txt_desc = new QLineEdit();
QHBoxLayout* type_lay = new QHBoxLayout();
QLabel* lbl_type = new QLabel(QObject::tr("type"));
lbl_type->setAlignment(Qt::AlignCenter);
this->txt_type = new QLineEdit();
QHBoxLayout* dur_lay = new QHBoxLayout();
QLabel* lbl_dur = new QLabel(QObject::tr("duration"));
lbl_dur->setAlignment(Qt::AlignCenter);
this->txt_dur = new QLineEdit();
QHBoxLayout* op_lay = new QHBoxLayout();
this->add_btn = new QPushButton(QObject::tr("&Add"));
this->upd_btn = new QPushButton(QObject::tr("Updat&e"));
this->rm_btn = new QPushButton(QObject::tr("&Remove"));
QHBoxLayout* fil_lay = new QHBoxLayout();
this->fil_desc_btn = new QPushButton(QObject::tr("FilterBy&Desc"));
this->fil_type_btn = new QPushButton(QObject::tr("FilterBy&Type"));
this->fil_search_btn = new QPushButton(QObject::tr("&Search"));
QHBoxLayout* undo_lay = new QHBoxLayout();
this->undo_btn = new QPushButton(QObject::tr("U&ndo"));
this->shuffle_btn = new QPushButton(QObject::tr("S&huffle"));
this->refresh_btn = new QPushButton(QObject::tr("Re&fresh"));
this->activities = new QListWidget();
main_lay->addLayout(left_lay);
main_lay->addLayout(right_lay);
title_lay->addWidget(lbl_title);
title_lay->addStretch();
title_lay->addWidget(txt_title);
desc_lay->addWidget(lbl_desc);
desc_lay->addStretch();
desc_lay->addWidget(txt_desc);
type_lay->addWidget(lbl_type);
type_lay->addStretch();
type_lay->addWidget(txt_type);
dur_lay->addWidget(lbl_dur);
dur_lay->addStretch();
dur_lay->addWidget(txt_dur);
op_lay->addWidget(add_btn);
op_lay->addWidget(upd_btn);
op_lay->addWidget(rm_btn);
fil_lay->addWidget(fil_desc_btn);
fil_lay->addWidget(fil_type_btn);
fil_lay->addWidget(fil_search_btn);
undo_lay->addWidget(refresh_btn);
undo_lay->addWidget(shuffle_btn);
undo_lay->addWidget(undo_btn);
right_lay->addLayout(title_lay);
right_lay->addLayout(desc_lay);
right_lay->addLayout(type_lay);
right_lay->addLayout(dur_lay);
right_lay->addLayout(op_lay);
right_lay->addLayout(fil_lay);
right_lay->addLayout(undo_lay);
QHBoxLayout* sort_lay = new QHBoxLayout();
this->sort_title_btn = new QPushButton(QObject::tr("SortByTit&le"));
this->sort_desc_btn = new QPushButton(QObject::tr("SortByDes&c"));
this->sort_type_btn = new QPushButton(QObject::tr("SortByT&ype"));
left_lay->addWidget(activities);
left_lay->addLayout(sort_lay);
sort_lay->addWidget(sort_title_btn);
sort_lay->addWidget(sort_desc_btn);
sort_lay->addWidget(sort_type_btn);
this->refresh_list();
}
void GUI::connect_gui()
{
QObject::connect(add_btn, SIGNAL(clicked()), this, SLOT(add()));
QObject::connect(upd_btn, SIGNAL(clicked()), this, SLOT(edit()));
QObject::connect(rm_btn, SIGNAL(clicked()), this, SLOT(remove()));
QObject::connect(sort_title_btn, SIGNAL(clicked()), this, SLOT(search()));
QObject::connect(undo_btn, SIGNAL(clicked()), this, SLOT(undo()));
QObject::connect(refresh_btn, SIGNAL(clicked()), this, SLOT(refresh_list()));
QObject::connect(fil_search_btn, SIGNAL(clicked()), this, SLOT(search()));
// QObject::connect(sort_title_btn, SIGNAL(clicked()), this, SLOT(sort_title()));
QObject::connect(sort_type_btn, SIGNAL(clicked()), this, SLOT(sort_type()));
QObject::connect(sort_desc_btn, SIGNAL(clicked()), this, SLOT(sort_desc()));
QObject::connect(shuffle_btn, SIGNAL(clicked()), this, SLOT(shuffle()));
QObject::connect(fil_desc_btn, SIGNAL(clicked()), this, SLOT(filter_desc()));
QObject::connect(fil_type_btn, SIGNAL(clicked()), this, SLOT(filter_type()));
}
Main problem is the button "sort_title_btn" which when connected to an empty method or not at all connected gives me the error when clicked.
The creation of the project was done by:
qmake -project
Editing the .pro file to add QT += core gui widgets and to include the folder with headers.
qmake
And finally: make
Compiles nicely, all buttons work except "sort_title_btn" even when NOT connected to a SLOT and "search" if the field by which the search has to be made is empty, that's not a problem for it can be fixed easily.
So, what is there to be done for the "sort_title_btn"?
I tried to put it to another SLOT, it works. Changing the name of the function I connect it to seems to bug out or something giving me the error.

Qt, crash when QStackedWidget's button try to access to another QStackedWidget's label

Main creates two QStackedWidget, class Body and class Bottom.
In class Body there is a button and when it is pressed it should change the text in the label in Bottom. The program crash when Body->button try to use the public function of Bottom which change the private label.
main.cpp
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//GRAPHIC INTERFACE
QStackedWidget *stackedWidget_body = new QStackedWidget;
QStackedWidget *stackedWidget_bottom = new QStackedWidget;
//create classe
Body * wBody ;
Bottom *wBottom;
wBody = new Body(wBottom); //pass the reference of the Bottom class, wBottom
wBottom = new Bottom();
//wBottom->setLLabel(); //this command will change the name of the label, it means that setLLabel works well
//insert the body widget
stackedWidget_body->addWidget(wBody);
//insert the bottom widget
stackedWidget_bottom->addWidget(wBottom);
//layout
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(stackedWidget_body);
layout->addWidget(stackedWidget_bottom);
//WINDOW
QWidget window;
window.setLayout(layout);
window.show();
a.exec();
return 0 ;
}
Body.h
namespace Ui {
class Body;
}
class Body : public QWidget
{
Q_OBJECT
public:
explicit Body(Bottom *_wBottom, QWidget *parent = 0);
~Body();
public slots:
void test(); // it will be called then the button will be pressed
private:
Ui::Body *ui;
Bottom *wBottom;
void testSend(Bottom *wBottom);
};
Body.cpp
Body::Body(Bottom *_wBottom, QWidget *parent) :
wBottom(_wBottom),
QWidget(parent),
ui(new Ui::Body)
{
QPushButton *button_standard2 = new QPushButton("test");
connect(button_standard2, SIGNAL(clicked(bool)),this, SLOT(test()));
//layout
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(button_standard2);
this->setLayout(layout);
ui->setupUi(this);
}
Body::~Body()
{delete ui;}
void Body::test(){
testSend(wBottom);
}
void Body::testSend(Bottom *wBottomX)
{
wBottomX->setLLabel();
}
bottom.h
namespace Ui {
class Bottom;
}
class Bottom : public QWidget
{
Q_OBJECT
public:
explicit Bottom(QWidget *parent = 0);
~Bottom();
void setLLabel();
private:
Ui::Bottom *ui;
QLabel *bLabel;
};
bottom.cpp
Bottom::Bottom(QWidget *parent) :
QWidget(parent),
ui(new Ui::Bottom)
{
bLabel = new QLabel("Name");
//layout
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(bLabel);
//setLLabel(); //this functions does it work
this->setLayout(layout);
ui->setupUi(this);
}
Bottom::~Bottom()
{delete ui;}
void Bottom::setLLabel(){
std::cout<<"change";
Bottom::bLabel->setText("value"); //The problem is here, when the function is called from Body::testSend
}
Can you give me any tip?
//create classe
Body * wBody ;
Bottom *wBottom;
wBody = new Body(wBottom); //pass the reference of the Bottom class, wBottom
wBottom = new Bottom();
You are sending an invalid wBottom instance to wBody. Try interchanging the last two lines.

QT separator widget?

Greetings all,
Is there any widget to separate two QWidgets and also give full focus to a one widget.
As shown in following figure ?
Thanks in advance,
umanga
How about QSplitter?
QWidget 1, for exmaple, QListView. QWidget 2 is a combination of QWidgets (the left part is simple QPushButton with show/hide caption, and the right part another widget)... All you have to do, is to hide your QWidget2 when user clicked on QPushButton...
If you need an example, I may post it.
Updated
main.cpp
#include "splitter.h"
#include <QtGui/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
splitter w;
w.show();
return a.exec();
}
splitter.h
#ifndef SPLITTER_H
#define SPLITTER_H
#include <QtGui/QDialog>
class splitter : public QDialog
{
Q_OBJECT;
QWidget* widget1;
QWidget* widget2;
QPushButton* button;
public:
splitter(QWidget *parent = 0, Qt::WFlags flags = 0);
~splitter();
private slots:
void showHide(void);
};
#endif // SPLITTER_H
splitter.cpp
#include <QtGui>
#include "splitter.h"
splitter::splitter(QWidget *parent, Qt::WFlags flags)
: QDialog(parent, flags)
{
QApplication::setStyle("plastique");
QListView* listView = new QListView;
QTableView* tableView = new QTableView;
button = new QPushButton("Hide >");
widget1 = new QWidget;
QHBoxLayout* w1Layout = new QHBoxLayout;
w1Layout->addWidget(listView);
w1Layout->addWidget(button);
widget1->setLayout(w1Layout);
widget2 = new QWidget;
QHBoxLayout* w2Layout = new QHBoxLayout;
w2Layout->addWidget(tableView);
widget2->setLayout(w2Layout);
QSplitter *mainSplitter = new QSplitter(this);
mainSplitter->addWidget(widget1);
mainSplitter->addWidget(widget2);
connect(button, SIGNAL(clicked()), this, SLOT(showHide()));
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(mainSplitter);
setLayout(mainLayout);
}
splitter::~splitter()
{}
void splitter::showHide(void)
{
if (widget2->isVisible())
{ // hide
widget2->setVisible(false);
button->setText("< Show");
}
else
{ // show
widget2->setVisible(true);
button->setText("Hide >");
}
}

QWidget - resize animation

Say I have a QHBoxLayout where there are 2 QTextEdits and between them a button with an arrow to the right. When you click on the button, the right-side QTextEdit gradually closes by moving the left border until it meets the right one. Simultaneously, the right border of the left QTextEdit takes the place which the right QTextEdit released. And after pressing on the button, the state of the system is coming to the former one.
EDIT: In order to organize this I have done the following:
1) In header file:
class MyWidget : public QWidget
{
Q_OBJECT
QTextEdit *m_textEditor1;
QTextEdit *m_textEditor2;
QPushButton *m_pushButton;
QHBoxLayout *m_layout;
int m_deltaX;
public:
MyWidget(QWidget * parent = 0);
~MyWidget(){}
private slots:
void closeOrOpenTextEdit2(bool isClosing);
};
2) In the source file:
MyWidget::MyWidget(QWidget * parent):QWidget(parent),m_deltaX(0)
{
m_pushButton = new QPushButton(this);
m_pushButton->setText(">");
m_pushButton->setCheckable(true);
connect(m_pushButton, SIGNAL(clicked(bool)), this, SLOT(closeOrOpenTextEdit2(bool)));
m_textEditor1 = new QTextEdit(this);
m_textEditor1->setText("AAAAA AAAAAAAAAAA AAAAAAAAAAA AAAAAAA AAAAAAAAAAA AAAAAAAAAAA AA");
m_textEditor2 = new QTextEdit(this);
m_layout = new QHBoxLayout;
m_layout->addWidget(m_textEditor1);
m_layout->addWidget(m_pushButton);
m_layout->addWidget(m_textEditor2);
setLayout(m_layout);
}
void MyWidget::closeOrOpenTextEdit2(bool isClosing)
{
QPropertyAnimation *animation1 = new QPropertyAnimation(m_textEditor2, "geometry");
QPropertyAnimation *animation2 = new QPropertyAnimation(m_pushButton, "geometry");
QPropertyAnimation *animation3 = new QPropertyAnimation(m_textEditor1, "geometry");
if(isClosing) //close the second textEdit
{
m_pushButton->setText("<");
QRect te2_1 = m_textEditor2->geometry();
m_deltaX = te2_1.width()-3;
QRect te2_2(te2_1.x()+m_deltaX, te2_1.y(), 3 ,te2_1.height());
QRect pb_1 = m_pushButton->geometry();
QRect pb_2(pb_1.x()+m_deltaX, pb_1.y(), pb_1.width() ,pb_1.height());
QRect te1_1 = m_textEditor1->geometry();
QRect te1_2(te1_1.x(), te1_1.y(), te1_1.width()+m_deltaX, te1_1.height());
//animation->setDuration(10000);
animation1->setStartValue(te2_1);
animation1->setEndValue(te2_2);
animation2->setStartValue(pb_1);
animation2->setEndValue(pb_2);
animation3->setStartValue(te1_1);
animation3->setEndValue(te1_2);
}
else //open
{
m_pushButton->setText(">");
QRect te2_1 = m_textEditor2->geometry();
QRect te2_2(te2_1.x()-m_deltaX, te2_1.y(), 3+m_deltaX ,te2_1.height());
QRect pb_1 = m_pushButton->geometry();
QRect pb_2(pb_1.x()-m_deltaX, pb_1.y(), pb_1.width() ,pb_1.height());
QRect te1_1 = m_textEditor1->geometry();
QRect te1_2(te1_1.x(), te1_1.y(), te1_1.width()-m_deltaX, te1_1.height());
//animation->setDuration(10000);
animation1->setStartValue(te2_1);
animation1->setEndValue(te2_2);
animation2->setStartValue(pb_1);
animation2->setEndValue(pb_2);
animation3->setStartValue(te1_1);
animation3->setEndValue(te1_2);
}
animation1->start();
animation2->start();
animation3->start();
}
EDIT:
And I have the following problem:
When I close the second QTextEdit (by clicking on the button) and resize the MyWidget, then the QTextEdit restores its state (but it should stay closed of course). How can I solve this problem?
Please provide me with a code snippet.
Qt's Animation framework sounds like a good place to start. You could just try to follow their tutorials, adapting for you use case. I have used it already, and it seemed quite straight forward.
1) You could replace your button with a vertical layout, place the button inside this layout and finally add a vertical spacer below the button (in same the layout).
...
QVBoxLayout* m_buttonLayout = new QVBoxLayout();
m_layout = new QHBoxLayout();
m_layout->addWidget(m_textEditor1);
m_layout->addLayout(m_buttonLayout);
m_layout->addWidget(m_textEditor2);
m_buttonLayout->addWidget(m_pushButton);
m_buttonLayout->addItem( new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding) );
2) I guess you could (and should) animate widget's maximumSize (or just maximumWidth) property and let the layout take care of calculating actual geometries. This would also simplify your calculations. E.g.
QPropertyAnimation *animation1 = new QPropertyAnimation(m_textEditor2, "maximumWidth");
QPropertyAnimation *animation2 = new QPropertyAnimation(m_textEditor, "maximumWidth");
if (isClosing)
{
int textEdit2_start = m_textEditor2->maximumWidth();
int textEdit2_end = 0;
int textEdit_start = m_textEditor->maximumWidth();
int textEdit_end = textEdit_start + textEdit2_start;
animation1->setStartValue(textEdit2_start);
...
}
Also, now you don't have to animate buttons geometry at all (assuming that you have set fixed size to it).
PS. I didn't compile codes so there might be minor errors but you should get the idea.
Here what I wanted:
Header file
class MyWidget : public QWidget
{
Q_OBJECT
QTextEdit *m_textEditor1;
QTextEdit *m_textEditor2;
QPushButton *m_pushButton;
QHBoxLayout *m_layout;
QVBoxLayout *m_buttonLayout;
int m_deltaX;
bool m_isClosed;
public:
MyWidget(QWidget * parent = 0);
~MyWidget(){}
void resizeEvent( QResizeEvent * event );
private slots:
void closeOrOpenTextEdit2(bool isClosing);
};
Source file
MyWidget::MyWidget(QWidget * parent):QWidget(parent),m_deltaX(0)
{
m_pushButton = new QPushButton(this);
m_pushButton->setText(">");
m_pushButton->setCheckable(true);
m_pushButton->setFixedSize(16,16);
connect(m_pushButton, SIGNAL(clicked(bool)), this, SLOT(closeOrOpenTextEdit2(bool)));
m_textEditor1 = new QTextEdit(this);
m_textEditor1->setText("AAAAA AAAAAAAAAAA AAAAAAAAAAA AAAAAAA AAAAAAAAAAA AAAAAAAAAAA AA");
m_textEditor2 = new QTextEdit(this);
m_buttonLayout = new QVBoxLayout();
m_buttonLayout->addWidget(m_pushButton);
m_buttonLayout->addItem( new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding) );
m_layout = new QHBoxLayout;
m_layout->addWidget(m_textEditor1, 10);
m_layout->addSpacing(15);
m_layout->addLayout(m_buttonLayout);
m_layout->setSpacing(0);
m_layout->addWidget(m_textEditor2, 4);
setLayout(m_layout);
resize(800,500);
}
void MyWidget::closeOrOpenTextEdit2(bool isClosing)
{
m_isClosed = isClosing;
QPropertyAnimation *animation1 = new QPropertyAnimation(m_textEditor2, "maximumWidth");
if(isClosing) //close the second textEdit
{
m_textEditor2->setMaximumWidth(m_textEditor2->width());
int textEdit2_start = m_textEditor2->maximumWidth();
m_deltaX = textEdit2_start;
int textEdit2_end = 3;
animation1->setDuration(500);
animation1->setStartValue(textEdit2_start);
animation1->setEndValue(textEdit2_end);
m_pushButton->setText("<");
}
else //open
{
int textEdit2_start = m_textEditor2->maximumWidth();
int textEdit2_end = m_deltaX;
animation1->setDuration(500);
animation1->setStartValue(textEdit2_start);
animation1->setEndValue(textEdit2_end);
m_pushButton->setText(">");
}
animation1->start();
}
void MyWidget::resizeEvent( QResizeEvent * event )
{
if(!m_isClosed)
m_textEditor2->setMaximumWidth( QWIDGETSIZE_MAX );
}