我很难在 Qt5 框架中实现自己的 MVC 方法。
我创建了自己的自定义项目类,从 QAbstractItemModel 派生了我的模型类,从 QStyledItemDelegate 派生了我的委托类,并将所有内容放在 QTreeView 中。
我已经尽可能地减少了我的代码以创建一个有点“最小”的例子。
我看到的是以下内容:我可以看到我的标题有 42,我可以看到一个条目说“测试项目”。尽管如此,当我双击后者或在选择它时按 F2 时 - 没有任何反应。'editTriggers' 调用返回 10,这意味着双击应该起作用(但它们不起作用)。我显然在这里遗漏了一些东西,但是经过几天自己试图弄清楚之后,我不得不承认我不知道。这是我的程序:
编辑开始,11 月 28 日
正如@eyllanesc 向我提议的那样,为了方便起见,我建立了一个小的 Github 存储库。链接在这里:
https://github.com/phyz777/DelegateTest.git
编辑结束,11 月 28 日
主.cpp:
int main(int argc, char* argv[]){
QApplication a(argc, argv);
MainWindow w;
w.showFullScreen();
return a.exec();
}
主窗口.hpp:
class MainWindow : public QMainWindow{
Q_OBJECT
public:
MainWindow(QWidget* parent = 0);
~MainWindow();
private slots:
private:
TestModel model;
};
主窗口.cpp:
MainWindow::MainWindow(QWidget *parent)
:QMainWindow(parent),
model(){
this->model.insertTestItem(new TestClass());
QTreeView* treeView = new QTreeView(this);
treeView->setItemDelegate(new TestModelItemDelegate());
treeView->setModel(&this->model);
treeView->setRootIndex(this->model.index(0, 0, QModelIndex()));
std::cout << "Edit triggers: " << (int)treeView->editTriggers() << std::endl;
this->setCentralWidget(treeView);
}
MainWindow::~MainWindow(){
;
}
测试模型.hpp:
class TestModel:public QAbstractItemModel{
public:
TestModel();
~TestModel();
int rowCount(QModelIndex const& =QModelIndex()) const;
int columnCount(QModelIndex const& =QModelIndex()) const;
QModelIndex index(int, int, QModelIndex const& =QModelIndex()) const;
QModelIndex parent(QModelIndex const&) const;
QVariant headerData(int, Qt::Orientation, int=Qt::DisplayRole) const;
QVariant data(const QModelIndex&, int=Qt::DisplayRole) const;
Qt::ItemFlags flags(QModelIndex const&);
bool setHeaderData(int, Qt::Orientation, QVariant const&, int);
bool setData(QModelIndex const&, QVariant const&, int);
void insertTestItem(TestClass*);
RootItem* getRoot();
private:
RootItem* root;
};
测试模型.cpp:
TestModel::TestModel()
:root(new RootItem()){
}
TestModel::~TestModel(){
}
int TestModel::rowCount(QModelIndex const& parent) const{
TestModelItemBase* itemBase =
reinterpret_cast<TestModelItemBase*>(parent.internalPointer());
switch(itemBase->getItemType()){
case TestModelItemBase::ITEM_TYPE::ROOT:
{
RootItem* item = dynamic_cast<RootItem*>(itemBase);
return item->getList().size();
}
case TestModelItemBase::ITEM_TYPE::TEST_ITEM:
{
TestModelItem* item = dynamic_cast<TestModelItem*>(itemBase);
return 0;
}
default:
return -1;
}
}
int TestModel::columnCount(QModelIndex const& parent) const{
return 1;
}
QModelIndex TestModel::index(int row, int column, QModelIndex const& parent) const{
if(0!=column){
return QModelIndex();
}
if(!parent.isValid()){
if(row==0){
return this->createIndex(0, 0, this->root);
}
return QModelIndex();
}
TestModelItemBase* parentItemBase = reinterpret_cast<TestModelItemBase*>(parent.internalPointer());
TestModelItemBase::ITEM_TYPE itemType = parentItemBase->getItemType();
switch(itemType){
case TestModelItemBase::ITEM_TYPE::ROOT:
{
RootItem* parentItem = dynamic_cast<RootItem*>(parentItemBase);
return this->createIndex(row, 0, reinterpret_cast<void*>(parentItem->getList().at(row)));
}
case TestModelItemBase::ITEM_TYPE::TEST_ITEM:
return QModelIndex();
default:
return QModelIndex();
}
}
QModelIndex TestModel::parent(QModelIndex const& index) const{
TestModelItemBase* parent =
reinterpret_cast<TestModelItemBase*>(index.internalPointer());
return this->createIndex(parent->getIndex(), 0,
reinterpret_cast<void*>(parent->getParent()));
}
QVariant TestModel::headerData(int section, Qt::Orientation orientation, int role) const{
if (0==section && Qt::Orientation::Horizontal==orientation && Qt::DisplayRole==role) {
int i = 42;
return QVariant(i);
} else {
return QVariant();
}
}
QVariant TestModel::data(QModelIndex const& index, int role) const{
TestModelItemBase* item = reinterpret_cast<TestModelItemBase*>(index.internalPointer());
if(Qt::DisplayRole==role){
switch(item->getItemType()){
case TestModelItemBase::ITEM_TYPE::TEST_ITEM:
return QString("Test item");
default:
return QString("");
}
}else{
if(Qt::EditRole==role){
QMessageBox::information(nullptr, "Model data", "We have an edit role");
}
if(Qt::UserRole==role){
QMessageBox::information(nullptr, "Model data", "We have a user role");
}
return QVariant();
}
}
Qt::ItemFlags TestModel::flags(QModelIndex const&){
QMessageBox::information(nullptr, "Model Flags", "Selectable, Editable, Enabled");
return (Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
}
bool TestModel::setHeaderData(int, Qt::Orientation, const QVariant&, int){
QMessageBox::information(nullptr, "Set header data", "Just return true");
return true;
}
bool TestModel::setData(const QModelIndex&, const QVariant&, int){
QMessageBox::information(nullptr, "Set data", "Just return true");
return true;
}
void TestModel::insertTestItem(TestClass* testClass){
if(nullptr==testClass){
QMessageBox::critical(nullptr, "Critical", "Not inserting nullptr");
return;
}
TestModelItem* child = new TestModelItem(testClass, this->root->size(), this->root);
this->beginInsertRows(this->createIndex(0, 0, reinterpret_cast<void*>(this->root)),
this->root->size(), this->root->size());
this->root->appendChild(child);
this->endInsertRows();
}
RootItem* TestModel::getRoot(){
return this->root;
}
testmodelitem.hpp:
class TestModelItemBase{
public:
enum class ITEM_TYPE{
ISNULL, INVALID, ROOT, TEST_ITEM
};
TestModelItemBase();
TestModelItemBase(ITEM_TYPE, int, TestModelItemBase*);
virtual ~TestModelItemBase();
ITEM_TYPE getItemType() const;
int getIndex() const;
TestModelItemBase* getParent();
virtual int size();
private:
ITEM_TYPE itemType;
int index;
TestModelItemBase* parent;
};
class RootItem;
class TestModelItem;
class TestClass;
class RootItem:public TestModelItemBase{
public:
RootItem();
~RootItem();
QList<TestModelItem*>& getList();
void appendChild(TestModelItem*);
virtual int size();
private:
QList<TestModelItem*> list;
};
class TestModelItem:public TestModelItemBase{
public:
TestModelItem(TestClass*, int, RootItem*);
~TestModelItem();
TestClass* getData();
virtual int size();
private:
TestClass* data;
};
class TestClass{
};
testmodelitem.cpp:
TestModelItemBase::TestModelItemBase()
:itemType(TestModelItemBase::ITEM_TYPE::INVALID), index(-1), parent(nullptr){
}
TestModelItemBase::TestModelItemBase(TestModelItemBase::ITEM_TYPE type, int i, TestModelItemBase* p)
:itemType(type), index(i), parent(p){
}
TestModelItemBase::~TestModelItemBase(){
}
TestModelItemBase::ITEM_TYPE TestModelItemBase::getItemType() const{
if(nullptr==this){
return TestModelItemBase::ITEM_TYPE::ISNULL;
}
return this->itemType;
}
int TestModelItemBase::getIndex() const{
if(nullptr==this){
return -2;
}
return this->index;
}
TestModelItemBase* TestModelItemBase::getParent(){
if(nullptr==this){
return nullptr;
}
return this->parent;
}
int TestModelItemBase::size(){
return -1;
}
RootItem::RootItem()
:TestModelItemBase(TestModelItemBase::ITEM_TYPE::ROOT,
0, nullptr){
}
RootItem::~RootItem(){
}
QList<TestModelItem*>& RootItem::getList(){
return this->list;
}
void RootItem::appendChild(TestModelItem* child){
this->list.append(child);
}
int RootItem::size(){
return this->list.size();
}
TestModelItem::TestModelItem(TestClass* d, int index, RootItem* parent)
:data(d),
TestModelItemBase(TestModelItemBase::ITEM_TYPE::TEST_ITEM,
index, parent){
}
TestModelItem::~TestModelItem(){
}
TestClass* TestModelItem::getData(){
return this->data;
}
int TestModelItem::size(){
return 0;
}
testmodelitemdelegate.hpp:
class TestModelItemDelegate:public QStyledItemDelegate{
Q_OBJECT
public:
TestModelItemDelegate();
~TestModelItemDelegate();
QWidget* createEditor(QWidget*, QStyleOptionViewItem const&, QModelIndex const&) const override;
void setEditorData(QWidget*, QModelIndex const&) const override;
void setModelData(QWidget*, QAbstractItemModel*, QModelIndex const&);
void updateEditorGeometry(QWidget* editor, QStyleOptionViewItem const& option,
QModelIndex const& index) const;
private:
QWidget* createTestEditor(QWidget*) const;
};
testmodelitemdelegate.cpp:
TestModelItemDelegate::TestModelItemDelegate(){
;
}
TestModelItemDelegate::~TestModelItemDelegate(){
;
}
QWidget* TestModelItemDelegate::createEditor(QWidget* parent,
QStyleOptionViewItem const& option,
QModelIndex const& index) const{
QMessageBox::information(nullptr, "Create editor", "Creating editor...");
TestModelItemBase* item = reinterpret_cast<TestModelItemBase*>(index.internalPointer());
switch(item->getItemType()){
case TestModelItemBase::ITEM_TYPE::TEST_ITEM:
return TestModelItemDelegate::createTestEditor(parent);
default:
break;
}
}
void TestModelItemDelegate::setEditorData(QWidget*, QModelIndex const&) const{
QMessageBox::information(nullptr, "Set editor data", "Doing nothing");
}
void TestModelItemDelegate::setModelData(QWidget*, QAbstractItemModel*,
QModelIndex const&){
QMessageBox::information(nullptr, "Set model data", "Doing nothing");
}
void TestModelItemDelegate::updateEditorGeometry(QWidget* editor, QStyleOptionViewItem const& option,
QModelIndex const& index) const{
QMessageBox::information(nullptr, "Update editor geometry", "Doing nothing");
}
QWidget* TestModelItemDelegate::createTestEditor(QWidget* parent) const{
QMessageBox::information(nullptr, "Create test editor", "Editor for testing");
QWidget* editor = new QWidget(parent);
QHBoxLayout* layout = new QHBoxLayout(editor);
layout->addWidget(new QPushButton(editor));
layout->addWidget(new QLineEdit(editor));
editor->setLayout(layout);
return editor;
}
我截断了所有包含的内容。我非常感谢提供的任何帮助。提前致谢!