- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我从 QAbstractItemModel 实现了一个派生类,它似乎工作正常。然后我创建了一个 QItemSelectionModel 并将其分配给提到的 QAbstractItemModel。
我的 QAbstractItemModel 不是小部件,也不会显示,只管理一个层次结构。When the selection is changed, and the QItemSelection model emits the selection changed signal the QItemSelections selected and deselected seem to contain the right data.
当我调用他们的::indexes() 函数来获取所选项目的索引时,问题就出现了,它没有返回任何项目,即使我知道项目被选中并且::width() 和::height()函数返回正确的值。
基本示例代码:(以下是演示问题的工作示例和文件)
class DerivedModel : public QAbstractItemModel {
DerivedModel(QObject* parent) : QAbstractItemModel(parent)
,m_selectionModel(nullptr)
{
//create the selection model and assign this model to it
m_selectionModel = new QItemSelectionModel(this, this);
}
...
//all needed overload functions
//the DerivedModel works great
...
private:
QItemSelectionModel* m_selectionModel;
}
//in a different object called SceneModel (a QGraphicsScene which shows graphical items based on the DerivedModel) which is connected to the selection models selectionChanged() signal I query the new selection
SceneModel::setSelectedItems(const QItemSelection& selected, const QItemSelection& deselected){
int selectionSize_A = selected.size(); //this returns correct number of selected items
int selectionSize_B = selected.indexes().size(); //this returns 0 -> WRONG
int selectionSize_C = selected.value(0).indexes().size(); //this returns 0 -> WRONG
int selectionSize_CA = selected.value(0).width(); //this returns correct
int selectionSize_CB = selected.value(0).height(); //this returns correct
//if I purposefully try to access the 1st selected index via QItemSelectionRange::topLeft() all is good and I get the index:
QItemSelectionRange range = selected.value(0);
QModelIndex topLeft = range.topLeft(); //cool, i get the 1st selected index
//it seems there is a problem with the ::indexes function, so dived into the Qt5 source and basically implemented again whats done there and it works.
}
包含 cmake 构建文件的链接: https://drive.google.com/file/d/0Bz03DnXr46WXYXRCeExtaHZadUU/view?usp=sharing
那里发生了什么:创建一个 DerivedModel 并在根项 (ROOT) 下保存 2 个项(A 和 B)。按下按钮会向 QItemSelectionModel 发出选择/取消选择 A 或 B 的信号。如果在模型中找到该项目,则打印“Found Item :)”,表明该项目存在并且可用于模型。QGraphicsView 包含一个场景(派生自 QGraphicsScene)。该场景是空的,仅代表一个从选择模型接收 selectionChange 信号的对象。当它收到该信号时,它会打印“Scene received item selection change”,这样我们就可以看到信号已经通过。然后是真正的东西:
如果有人知道某事,或者发现我的方法有错误,请告诉我。谢谢!
Linux Manjaro Gcc 4.9.1 Qt5.3
派生模型.h:
#ifndef DERIVEDMODEL_H
#define DERIVEDMODEL_H
#include <QAbstractItemModel>
//fwd declaration
QT_FORWARD_DECLARE_CLASS(QItemSelectionModel)
class Item;
class DerivedModel : public QAbstractItemModel{
Q_OBJECT
public:
//model is a singleton, function to get instance
static DerivedModel& instance();
explicit DerivedModel(QObject* parent);
virtual ~DerivedModel();
/////////////////model overloads//////////////////////////////
QVariant data(const QModelIndex& index, int role) const;
Qt::ItemFlags flags(const QModelIndex& index) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex& index) const;
int rowCount(const QModelIndex& parent = QModelIndex()) const;
int columnCount(const QModelIndex& parent = QModelIndex()) const {Q_UNUSED(parent); return 1;}
//////////////////////////////////////////////////////////////
//get the item from an index
Item* item(const QModelIndex& index) const { return static_cast<Item*>(index.internalPointer());}
//get the index from an item name
const QModelIndex indexFromName(const QString& name);
//add an item
void addItem(const QString& name, Item* parent=nullptr);
//get the selection model
QItemSelectionModel* selectionModel() const {return m_selectionModel;}
private:
//the instance of the singleton to return
static DerivedModel* m_instance;
//the root object for the model
//never actually used
Item* m_rootItem;
//selection model for handeling selection
QItemSelectionModel* m_selectionModel;
};
#endif
派生模型.cpp
#include "DerivedModel.h"
#include "Item.h"
#include <QItemSelectionModel>
#include <QDebug>
//init static member
DerivedModel* DerivedModel::m_instance = nullptr;
DerivedModel& DerivedModel::instance(){
//check if set
if(!m_instance){
qDebug() << "ERROR model instance not set";
std::abort();
}
return *m_instance;
}
DerivedModel::DerivedModel(QObject* parent):
QAbstractItemModel(parent)
,m_rootItem(nullptr)
,m_selectionModel(nullptr)
{
//set the instance
m_instance = this;
//creae root item
m_rootItem = new Item("ROOT");
//init selection model
m_selectionModel = new QItemSelectionModel(this, this);
}
DerivedModel::~DerivedModel(){
//selection model is child so gets deleted
}
QVariant DerivedModel::data(const QModelIndex& index, int role) const {
//if the index is valid
if(!index.isValid()) {
qDebug() << "Index not valid!";
return QVariant();
}
//switch role
switch(role){
case Qt::DisplayRole:{
QString name = static_cast<Item*>(index.internalPointer())->name();
return name;
break;
}
default:
return QVariant();
}
}
Qt::ItemFlags DerivedModel::flags(const QModelIndex& index) const {
//check valid
if(!index.isValid()) return 0;
return static_cast<Item*>(index.internalPointer())->flags();
}
QVariant DerivedModel::headerData(int section, Qt::Orientation orientation, int role) const {
//unused for now
Q_UNUSED(section);
Q_UNUSED(orientation);
if(role==Qt::DisplayRole) return QVariant("HeaderData");
else return QVariant();
}
QModelIndex DerivedModel::index(int row, int column, const QModelIndex& parent) const {
Item* parentItem(nullptr);
//is valid?
if(!parent.isValid()) {
parentItem = m_rootItem;
}
else {
parentItem = item(parent);
}
//child pointer holder
Item* childItem = parentItem->children().value(row);
//is null?
if(childItem){
return createIndex(row, column, childItem);
}
else {
return QModelIndex();
}
}
QModelIndex DerivedModel::parent(const QModelIndex& index) const {
//check valid
if(!index.isValid()) return QModelIndex();
//get child
Item* childItem = static_cast<Item*>(index.internalPointer());
//find parent
Item* parentItem = childItem->parent();
//is null?
if(parentItem == m_rootItem) return QModelIndex();
return createIndex(parentItem->parent()->children().indexOf(parentItem), 0, parentItem);
}
int DerivedModel::rowCount(const QModelIndex& parent) const {
//parent holder
Item* parentItem;
//check 0 column (not sure why, but is in example, maybe the model iterates also through different columns)
if(parent.column()>0) return 0;
//check valid
if(!parent.isValid()) parentItem = m_rootItem;
else parentItem = static_cast<Item*>(parent.internalPointer());
return parentItem->children().length();
}
const QModelIndex DerivedModel::indexFromName(const QString& name){
//make a match based on the name
//and return 1st match
QModelIndex index = match(DerivedModel::index(0,0,QModelIndex()),
Qt::DisplayRole, name, 1,
Qt::MatchFlags(Qt::MatchExactly|Qt::MatchRecursive))
.value(0);
return index;
}
void DerivedModel::addItem(const QString& name, Item* parent){
//check parent
if(!parent) parent = m_rootItem;
//create the item
//will be deleted once parent is deleted
new Item(name, parent);
}
项目.h:
#ifndef ITEM_H
#define ITEM_H
#include <QString>
#include <QList>
#include <QDebug>
class Item {
public:
Item(const QString& name, Item* parent=nullptr) :
m_name(name), m_parent(parent){
//add as child to parent
if(parent) parent->addChild(this);
//set the flag to enable selection
m_flags = Qt::ItemIsSelectable;
qDebug() << "Created Item "+name;
};
~Item(){
//delete children
for (auto& child : m_children){
delete child;
}
};
//get the name
const QString& name() const {return m_name;}
//get the flags
const Qt::ItemFlags& flags() const {return m_flags;}
//gte the parent
Item* parent() const {return m_parent;}
//get the children
const QList<Item*>& children() {return m_children;}
//add a child
void addChild(Item* item) {m_children.append(item);}
private:
//name
QString m_name;
//flags
Qt::ItemFlags m_flags;
//parent
Item* m_parent;
//list og children
QList<Item*> m_children;
};
#endif
场景.h:
#ifndef GRAPHICSSCENE_H
#define GRAPHICSSCENE_H
#include <QGraphicsScene>
//fwd dec
QT_FORWARD_DECLARE_CLASS(QItemSelection)
QT_FORWARD_DECLARE_CLASS(QGraphicsRectItem)
class Scene : public QGraphicsScene {
public:
Scene(QObject* parent);
virtual ~Scene(){}
public slots:
//pass the selection to the squares
void setSelection(const QItemSelection& selected, const QItemSelection& deselected);
};
#endif
场景.cpp:
#include "Scene.h"
#include "DerivedModel.h"
#include "Item.h"
#include <QItemSelectionModel>
#include <QGraphicsRectItem>
#include <QRect>
#include <QDebug>
Scene::Scene(QObject* parent) : QGraphicsScene(parent)
{
//connect to the models selection change
connect(DerivedModel::instance().selectionModel(), &QItemSelectionModel::selectionChanged,
this, &Scene::setSelection);
}
void Scene::setSelection(const QItemSelection& selected, const QItemSelection& deselected){
Q_UNUSED(deselected);
//testing changes
int A = selected.size();
int B = selected.indexes().size();
QModelIndex index = selected.value(0).topLeft();
QString name = "";
if(index.isValid()) name = static_cast<Item*>(index.internalPointer())->name();
qDebug() << "Scene recieved item selection change";
qDebug() << "Number of selected QItemRanges from source = "+QString::number(A);
qDebug() << "Number of selected INDEXES from source = "+QString::number(B);
qDebug() << "Manually accessd 1st index in 1st range returns item named: "+name;
}
小部件.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
//fwd dec
QT_FORWARD_DECLARE_CLASS(QPushButton)
QT_FORWARD_DECLARE_CLASS(QVBoxLayout)
QT_FORWARD_DECLARE_CLASS(QHBoxLayout)
QT_FORWARD_DECLARE_CLASS(QGraphicsView)
class DerivedModel;
class Scene;
class Widget : public QWidget{
public:
Widget(QWidget* parent=nullptr);
virtual ~Widget(){}
private slots:
//button toggle alot
void toggle(bool state);
private:
//layout
QVBoxLayout* m_mainVBLayout;
//horizontal layout for the buttons
QHBoxLayout* m_HBButtonsLayout;
//GraphicsView widget for the scene
QGraphicsView* m_graphicsView;
//the graphics scene recieving the change event where the problem is
Scene* m_scene;
//push buttons
QPushButton* m_button1;
QPushButton* m_button2;
//the DerivedModel
DerivedModel* m_model;
};
#endif
小部件.cpp:
#include "Widget.h"
#include "DerivedModel.h"
#include "Scene.h"
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGraphicsView>
#include <QDebug>
#include <QItemSelection>
Widget::Widget(QWidget* parent) : QWidget(parent)
,m_mainVBLayout(nullptr)
,m_HBButtonsLayout(nullptr)
,m_graphicsView(nullptr)
,m_scene(nullptr)
,m_button1(nullptr)
,m_button2(nullptr)
,m_model(nullptr)
{
//init the DerivedModel
m_model = new DerivedModel(this);
//add two items to the model
m_model->addItem("A");
m_model->addItem("B");
//create the main layout
m_mainVBLayout = new QVBoxLayout(this);
//create the buttons layout
m_HBButtonsLayout = new QHBoxLayout;
//add it to the main layout
m_mainVBLayout->addLayout(m_HBButtonsLayout);
//create the buttons
m_button1 = new QPushButton("A", this);
m_button2 = new QPushButton("B", this);
//set them to be checkable
m_button1->setCheckable(true);
m_button2->setCheckable(true);
//connect their signals
connect(m_button1, &QPushButton::toggled, this, &Widget::toggle);
connect(m_button2, &QPushButton::toggled, this, &Widget::toggle);
//add them to the layout
m_HBButtonsLayout->addWidget(m_button1);
m_HBButtonsLayout->addWidget(m_button2);
//create the graphics view
m_graphicsView = new QGraphicsView(this);
//create the scene
m_scene = new Scene(this);
m_scene->setSceneRect(QRect(0,0,50,25));
//set its scene
m_graphicsView->setScene(m_scene);
//add the graphics view to the layout
m_mainVBLayout->addWidget(m_graphicsView);
}
void Widget::toggle(bool state){
//get the sender
QPushButton* button(nullptr);
if(sender()==m_button1) button = m_button1;
else button = m_button2;
//get the name of the item related to the button to change
QString name = button->text();
//get the index based on the name
//im using the instance of the DerivedModel because this is how I implement it in my project;
QModelIndex itemIndex = DerivedModel::instance().indexFromName(name);
//check if index is valid
if(!itemIndex.isValid()){
qDebug() << "Index for item "+name+" not valid!";
return;
}
else
qDebug() << "Found Item :)";
//create a QItemSelection as how it is in my project
QItemSelection selection;
//add the index to the selection
selection.select(itemIndex, itemIndex);
//check the state
if(state){
//add to the selection
DerivedModel::instance().selectionModel()->select(selection, QItemSelectionModel::Select);
}
else{
//remove from selection
DerivedModel::instance().selectionModel()->select(selection, QItemSelectionModel::Deselect);
}
}
最佳答案
好的,所以我找到了罪魁祸首:)
以防其他人遇到同样的问题,我的错误出在派生的 QAbstractItemModel 类的::flags() 函数中:在定义中我没有调用基类 QAbstractItemModel::flags(index) 函数,一旦我调用它而不是自己返回标志,一切顺利。
所以我认为只要你的项目有一个模型可以调用的 Qt::flags flags() 函数,你就不必重新实现 QAbstractItemModel::flags() 函数。
似乎模型正在通过 QModelIndex::flags() 函数查询标志。
感谢“Ezee”和“Kuba Ober”愿意提供帮助。
关于c++ - Qt QItemSelection::indexes() 返回错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26361727/
我正在使用 Qt 语言学家翻译一个 ui 文件。我使用 lupdate 获取了它的 ts 文件,并翻译了这些单词和短语。现在我想将它添加到我的代码中,但我从它的教程中发现我似乎必须将 tr() 添加到
我想在 Qt Creator 中创建下面的简单控制台应用程序: #include int main(int argc, char* argv[]) { std::cout #include
我想将 libQtGui.so.4 libQtNetwork.so.4 和 libQtCore.so.4 包含在与我的应用程序所在的目录相同的目录中。我如何让 Qt 理解这一点? y 目的是拥有一个使
我有一个充满 QPushButtons 和 QLabels 以及各种其他有趣的 QWidget 的窗口,所有这些都使用各种 QLayout 对象动态布局...而我想做的是偶尔制作一些这些小部件变得不可
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 7 年前。 Improve
我想知道 Qt 是否将下面代码的“版本 1”之类的东西放在堆上?在版本 1 中,Qt 会将 dirStuff 放在堆栈上还是堆上?我问是因为我有一种感觉,Java 将所有数据结构放在堆上......不
这个问题是关于 Qt Installer Framework 2.0 版的。 在这一点上,使用 Qt 安装程序框架的人都知道,如果不进行自定义,您根本无法通过安装程序覆盖现有安装。这样做显然是为了解决
关闭。这个问题是off-topic .它目前不接受答案。 想改善这个问题吗? Update the question所以它是 on-topic对于堆栈溢出。 8年前关闭。 Improve this q
因为我在我的计算机上安装了 Qt 4.8.4 和 Qt 5.1,所以我遇到了问题。 当只有 Qt 4.8.4 存在时,一切都很好。 当我添加 Qt 5.1 时,这个工作正常,但 Qt 4.8.4 给了
我无法在我的 Ubuntu 12 中安装更多软件包。我尝试了 apt-get install -f ,以及许多其他类似的技巧,但在找到解决方案方面没有进展。 这是属于 Qt 的损坏包: 以下包具有未满
我正在尝试使用 Virtual Box 中的 Ubuntu 机器复制我们目前在物理 Ubuntu 服务器上运行的应用程序。它是一个 QT 应用程序,但在服务器上我们使用 NPM 的 pm2 运行它。安
问题: Qt Creator 是用 Qt Creator 构建的吗? 同样,Qt Designer 是用 Qt Designer 构建的吗? 顺便说一句,为什么有两个 Qt IDE?他们是竞争对手吗?
当我使用 QWidget设计用户界面时,我总是对它的大小属性有点困惑。有size policy , geometry和 hintSize . 我只知道size policy之间的关系和 hintSiz
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我想知道是否有一种很好的方法可以让用户像 LabView 一样创建节点图(有限制)。 像这样的东西: 我见过http://www.pyqtgraph.org/ ,这似乎有类似的东西,我确实打算使用 P
在 Qt 中是否有一种跨平台的方式来获得用户喜欢的固定宽度和比例字体? 例如,在 cocoa 中,有 NSFont *proportional = [NSFont userFontOfSize:12.
我想使用 Qt 和 C++ 制作这样的交互式图表:http://jsxgraph.uni-bayreuth.de/wiki/index.php/Cubic_spline_interpolation 关
我正在编写一个嵌入式设备屏幕的模拟(其中包含主 QWidget 顶部的自定义小部件),虽然屏幕的原始尺寸是 800x600,但我希望能够按比例放大和缩小它拖动窗口的角。如果不使用网格布局和担架(不会向
在下面的示例中,我是否必须从堆中删除对象?如果是的话,怎么办? #include #include #include #include #include int main(int argc,
来自 Web 开发背景,我现在进入 QT 应用程序开发。 使用 QFonts 我已经看到我显然只有两个选择,在 QT 中定义字体大小;按像素大小或点大小。 在制作网页布局时,我习惯于以相对方式定义所有
我是一名优秀的程序员,十分优秀!