Как я понял работу:
создаем на форму QTabWidget;
затем создаем классы, наследники QWidget;
в этих классам создаем нужные нам элементы GUI;
в класс нашего главного окна добавляем что то в духе:
tabWidget = new QTabWidget;
tabWidget->addTab(new newTab(), tr("Tab"));
.void WallWindow::something()
{
//...
ListTab my;
my.startButton->setText("Start");
//...
}
Это правильно?
1) можно произвести свой класс от вкладки и там сохранять указатель на родителя нужного класса
tabWidget->addTab(new newTab(tabWidget), tr("Tab"));Language: cpp
2) сигналы и слоты
1) не понял
2) как тогда изменить иконку главного окна кнопкой находящейся в табе?
1) произвести класс-вкладку от QWidget, в конструкторе принять указатель на QTabWidget-родитель. Когда нужно, просто вызываешь нужный метод по указателю
2) а как это обычно делается ? Также, только в слоте, а слот соединён с сигналом кнопки
А можно с примером кода. Так как я все равно не понял.
нет, пример сейчас я писать не в состоянии. А первый пункт - это классика C++ , в любом учебнике но нему есть
Спрошу еще раз, у всех.
Как вызвать функцию, которая определена в другом классе?
Пример:
.h
class ListTab : public QWidget
{
Q_OBJECT
public:
ListTab(QWidget *parent = 0);
public slots:
QFileInfoList load_and_show();
};
class settingTab : public QWidget
{
Q_OBJECT
public:
settingTab(QWidget *parent = 0);
private slots:
void on_addFolderButton_clicked();
};
А пример можно? Я ничего не понял.
тут нужно четко понимать что ты хочешь сделать. и не путать класс с экземпляром класса... Если QFileInfoList load_and_show() имеет статическую природу, тогда объяви эту функцию как статическую, если же данная функция имеет не статическую природу , тогда, в любом случае, придется иметь экземпляр одного класса в описании другого и с этим ничего не поделать.
class ListTab : public QWidget
{
Q_OBJECT
public:
ListTab(QWidget *parent = 0);
public slots:
QFileInfoList load_and_show();
};
class settingTab : public QWidget
{
Q_OBJECT
public:
settingTab(QWidget *parent = 0);
private slots:
void on_addFolderButton_clicked()
{
if (m_pListTab)
{
m_pListTab->load_and_show();
}
}
private:
ListTab* m_pListTab;
};
Блин!
Оно и до этого работало. Программа падала именно в load_and_show(), а не при определении класса.
Осталось понять в чем проблема.
вообще что то несвязное, код в студию. (весь)
Вот в чем проблема:
settingTab::settingTab(QWidget *parent) : QWidget(parent)
{
settings = new QSettings(QSettings::IniFormat, QSettings::UserScope,
"wallpapers-changer", "wallchanger");
addFolderButton = new QPushButton("Add folder",this);
connect(addFolderButton, SIGNAL(clicked()), this, SLOT(on_addFolderButton_clicked()));
}
void settingTab::on_addFolderButton_clicked()
{
QString selectedDir = QFileDialog::getExistingDirectory(this,
"Open Image(s)",
"/media/data",
QFileDialog::ShowDirsOnly);
folderListWidget->addItem(selectedDir);
dirList.append(selectedDir);
if (!dirList.isEmpty())
settings->setValue("settings/dirList",dirList);
if (!settings->value("settings/dirList").toStringList().isEmpty()) {
m_pListTab->load_and_show();
}
}
программа убивается на строке:
m_pListTab->load_and_show();
?Нет. При попытке прочесть QSettings в load_and_show();
Инициализация:
class settingTab : public QWidget
{
Q_OBJECT
public:
QSettings *settings;
...
private slots:
void on_addFolderButton_clicked();
private:
ListTab* m_pListTab;
};
возможно кинуть код проекта архивом, или архивом целиком файлы с данными классами, просто отрывки не отражают всей картины.
Проблема банальна, у тебя не инициализирована m_pListTab, т.е. адрес этого объекта = мусор. Инициализируй его в конструкторе класса settingTab
просто разыменование "мусора" ведет к непредсказуемому результату. это и вызывало падения...
Так что ли?
m_pListTab = new ListTab;
settingTab::settingTab(QWidget *parent) : QWidget(parent)
{
m_pListTab = new ListTab(this);
settings = new QSettings(QSettings::IniFormat, QSettings::UserScope,
"wallpapers-changer", "wallchanger");
picFolders = new QLabel("Pictures folders:",this);
addFolderButton = new QPushButton("Add folder",this);
connect(addFolderButton, SIGNAL(clicked()), this, SLOT(on_addFolderButton_clicked()));
folderListWidget = new QListWidget(this);
QGridLayout *my = new QGridLayout;
//QStringList dirList;
//dirList = new QStringList;
dirList = settings->value("settings/dirList").toStringList();
//dirList<<"/media/data/Additional/Pictures"<<"/media/data/Additional/Images";
my->addWidget(picFolders,0,0,1,3);
my->addWidget(folderListWidget,1,0,1,3);
my->addWidget(addFolderButton,2,0);
setLayout(my);
for (int i=0; i<dirList.count(); ++i) {
folderListWidget->addItem(dirList.at(i));
}
if (!dirList.isEmpty())
settings->setValue("settings/dirList",dirList);
}
Я так делал. Но таблица в первом табе не заполняется.
На счет совета: я знаю, просто ради интереса хотелось и в этом разобраться. Понять как оно изнутри работает.
settingTab::settingTab(ListTab* pListTab, QWidget *parent) : QWidget(parent)
{
m_pListTab = pListTab;
settings = new QSettings(QSettings::IniFormat, QSettings::UserScope,
"wallpapers-changer", "wallchanger");
...............
}
WallWindow::WallWindow()
{
........
listTab = new ListTab;
settTab = new settingTab(listTab);
........
}
Ура! Спасибо. Работает как надо.
Я бы сам не додумался до такого. Просто еще не разу с таким количеством классов не сталкивался.
Теперь по аналогии можно доделывать все что я хотел.
И снова эти табы!
Теперь проблема с Ui
.h
#ifndef WALLWINDOW_H
#define WALLWINDOW_H
#include <QMainWindow>
#include "ui_wallwindow.h"
class WallWindow : public QMainWindow, private Ui::WallWindow
{
Q_OBJECT
public:
WallWindow(QWidget *parent = 0);
};
class ListTab : public QWidget, private Ui::WallWindow
{
Q_OBJECT
public:
ListTab(QWidget *parent = 0);
public slots:
};
class folderTab : public QWidget, private Ui::WallWindow
{
Q_OBJECT
public:
folderTab(QWidget *parent = 0);
public slots:
};
#endif // WALLWINDOW_H
#include <QtDebug>
#include "wallwindow.h"
WallWindow::WallWindow(QWidget *parent)
: QMainWindow(parent)
{
setupUi(this);
//QWidget *mainWidget = new QWidget;
//mainWidget->setLayout(verticalLayout);
//setCentralWidget(mainWidget);
qDebug()<<gridLayout_2->rowCount();
gridLayout_2->setAlignment(spinBox,Qt::AlignRight);
}
ListTab::ListTab(QWidget *parent) : QWidget(parent)
{
//gridLayout_2->setAlignment(spinBox,Qt::AlignRight);
//setLayout(gridLayout_2);
//qDebug()<<gridLayout_2->rowCount();
//gridLayout_2->itemAtPosition(0,5)->setAlignment(Qt::AlignRight);
}
естественно не работает, потому что не правильно делаешь Выложи код если не трудно, посмотрю
Да знаю что не правильно. Тут то табы уже созданы. А если делать как я раньше делал, то нужно было их создавать.
Сделай проще архитектурно, у тебя есть один диалог с табом, причем табы не динамические.
Тут у тебя есть уже готовые объекты которыми будешь управлять из WallWindow.
ListTab и FolderTab у тебя вообще не используется, тк вся форма создается в дизайнере вместе с наполнением. У тебя есть доступ ко всем объектам табов по именам в любой части WallWindow, поэтому не стесняясь можно создавать нужные слоты в WallWindow и наполнять функциональностью.
P.S. не забывай нормально именовать объекты в QtDesigner, самому будет проще разбираться что к чему, тк имена переменных pushButton1, pushButton2 не информативны
class WallWindow : public QMainWindow, private Ui::WallWindow
{
Q_OBJECT
public:
WallWindow(QWidget *parent = 0);
private slots:
void on_addFolderButton_clicked();
void tableFill();
int setImage();
void processStart(QString path, QString arg);
QList<int> createRandomNumberList();
void startButton_clicked();
void on_onlynames_checkBox_stateChanged(int );
void on_timeBox_valueChanged(int );
void addButton_clicked();
void on_table_cellDoubleClicked(int row, int column);
void on_table_cellClicked(int row, int column);
void clearButton_clicked();
void on_pos_comboBox_currentIndexChanged(QString name);
void order_comboBox_currentIndexChanged(QString name);
void config_save();
void nextImage();
void previousImage();
void iconActivated(QSystemTrayIcon::ActivationReason reason);
};
Да-да. Это просто тестовый проект.
То есть, как я понял, допклассы создавать не нужно. Можно все реализовывать через WallWindow?
Тогда получается, что работать с дизайнером действительно проще
Дизайнер избавляет от "груды" однотипного и рутинного кода, экономя на этом время.
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)