2013-03-08 4 views
3

У меня есть пользовательский подкласс QTreeWidget, который я использую для отображения названий дорожек/etc. в моем проекте редактора MIDI (https://github.com/waddlesplash/ragingmidi). Я хотел бы добавить еще один столбец в этот виджет дерева, но с одним виджетами, занимающим весь столбец, а не виджеты для каждого элемента.Можете ли вы установить QWidget, чтобы взять весь столбец QTreeWidget?

Возможно ли это, или мне нужно выяснить какое-то другое решение?

EDIT: Я пытаюсь сделать что-то вроде этого: http://www.anvilstudio.com/compose.jpg - увидеть последний «столбец» в представлении заголовка (3-й после «L/R Баланс») с указанием всех линий/заметки (которые полностью пользовательский и написанный в VB.NET и закрытом исходном коде).

EDIT 2: Вы не можете увидеть его, но последний столбец прокручивается без прокрутки других столбцов на приведенном выше рисунке. В своем методе вам нужно прокручивать с помощью мыши. Мне нужна полоса прокрутки.

+0

Есть ли причина, по которой вы не можете просто поставить QtreeWidget слева от QWidget в QHBoxLayout? –

+0

Мне нужен QWidget для выравнивания с QTreeWidget, чтобы я мог рисовать собственные строки для столбца. Так что прокрутка - проблема. – waddlesplash

+1

Из любопытства: зачем вам нужен виджет, а не виджеты для каждой строки, которые могли бы общаться? –

ответ

0

хотя что пришло на мой взгляд, через неделю, чтобы захватить H-scrollbar для QTreeWidget, а затем заставьте эту полосу прокрутки прокрутить только последний столбец.Потому что прямо сейчас все столбцы подходят, когда окно 620x670px, и у кого больше экрана?

Если у кого-то нет лучшего решения или возражений относительно того, почему это плохая идея, так я собираюсь это сделать.

+0

Честно говоря, я не думаю, что это на самом деле отвечает на ваш первоначальный вопрос. И я все еще думаю, что я представил приемлемое решение, которое очень хорошо работает с Qt 4.8.4 и должно быть легко переноситься в Qt 5. Я считаю эту часть своей работой. Я подумаю дважды, чтобы ответить на ваши вопросы в следующий раз. Сожалею. –

+0

Я попробовал ваше решение и вставил ошибку. Я проверил, что существует «main.moc» (который я сгенерировал с помощью 'moc main.cpp -o main.moc'), а затем использовал' g ++ '4.7.2, чтобы попытаться скомпилировать его. Мой Qt не сломан; Я портировал другие приложения (включая мои) на Qt5, и никто не дал мне эту проблему. Я подумал об этом решении, которое кажется мне лучше, чем твое. Если вы видите фактический недостаток, скажите, пожалуйста, но я этого не сделаю. – waddlesplash

+0

Каким образом захват горизонтальной полосы прокрутки помогает отображать пользовательский виджет по всем строкам столбца? Кроме того, если у вас возникла проблема с этим материалом 'main.moc', просто разделите приложение примера на файлы' h' и 'cpp', как и на любой другой класс на основе Qt. И что касается вашей ошибки компиляции: метод 'connect()' наследуется от QObject и используется во всех приложениях на основе Qt. Таким образом, должно быть что-то совершенно неправильное в том, как вы компилируете здесь. Мне жаль, что я не могу сказать, что это от моего хрустального шара. –

2

Если посмотреть на документацию Qt, то, по-видимому, есть несколько вариантов для этого, однако есть несколько важных факторов для решения, прежде чем вы сможете решить, какой подход наилучшим образом соответствует вашим потребностям.

  1. Является ли содержимое отображаемым в этом столбце статического или динамического дерева?
  2. Есть ли один к одному сопоставление строк из вашего QTreeWidget с вашим настраиваемым столбцом дерева?

Если ваш пользовательский контент столбца дерева является статическим и существует одно к одному сопоставление строк, использование функции QTreeWidget::setItemWidget (QTreeWidgetItem * item, int column, QWidget * widget) должно быть достаточным.

Однако, если содержимое столбца настраиваемого дерева является динамическим или нет сопоставления строк по одному, это потребует более сложного подхода.

Как описано в документации для QTreeWidget; «Если вы хотите отобразить собственный динамический контент или реализовать собственный виджет редактора, используйте QTreeView и подкласс QItemDelegate.»

QItemDelegate и его подклассы выполняют все средства рисования для элементов, вставленных в представления элементов Qt (например, QTreeView, QListView , QTableView и т. Д.). Это, по сути, позволяет вам контролировать ВСЕ операции рисования для любого элемента, вставленного в класс QTreeView, позволяя вам рисовать динамический контент в дополнение к возможности расширения контента по нескольким строкам.

Внедрение аналогичного подхода для QListWidget, я рекомендую использовать QStyledItemDelegate вместо QItemDelegate, так как он позволяет более легко интегрировать этот виджет с макетом вашего приложения. Поскольку вы не детализировали точное использование этого пользовательского QWidget, вам также могут потребоваться дополнительные средства, предоставляемые QItemEditorCreator, QItemEditorCreatorBase и QItemEditorFactory. Я бы опубликовал аналогичный виджет, который я разработал здесь, если бы мог, но, к сожалению, это часть проприетарного программного пакета.

+0

Это динамический контент. И я уже использую setItemWidget() для добавления ползунков. См. Https://github.com/waddlesplash/ragingmidi/blob/master/src/Gui/Widgets/TracksEdit.cpp#L66 для всего кода как есть, без столбца, который я хочу добавить. – waddlesplash

0

Это не совсем красиво, потому что он получил это проблемы, когда пользовательский виджет в правой колонке и колонка сделана узкая, но это начало:

#include <QtGui> 

class TreeWidget : public QTreeWidget 
{ 
    Q_OBJECT 
public: 
    TreeWidget(); 

    QRect columnRect(int column) const; 

private slots: 
    void repositionColumnWidget(); 

private: 
    QPushButton * mColumnWidget; 
}; 

TreeWidget::TreeWidget() 
    : mColumnWidget(new QPushButton("Custom Column Button", viewport())) 
{ 
    const int COLUMN_COUNT = 6; 
    setColumnCount(COLUMN_COUNT); 
    for (int row = 0; row < 400; ++row) 
    { 
     QStringList columns; 
     for (int column = 0; column < COLUMN_COUNT; ++column) 
     { 
      columns << QString("row %1, column %2").arg(row + 1).arg(column + 1); 
     } 
     addTopLevelItem(new QTreeWidgetItem(columns)); 
    } 
    for (int column = 0; column < COLUMN_COUNT; ++column) 
    { 
     resizeColumnToContents(column); 
    } 
    repositionColumnWidget(); 
    mColumnWidget->show(); 
    connect(header(), SIGNAL(sectionResized(int,int,int)), this, SLOT(repositionColumnWidget())); 
    connect(header(), SIGNAL(sectionMoved(int,int,int)), this, SLOT(repositionColumnWidget())); 
    connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(repositionColumnWidget())); 
    connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(repositionColumnWidget())); 
} 

QRect TreeWidget::columnRect(int column) const 
{ 
    int itemCount = topLevelItemCount(); 
    if (!itemCount) 
    { 
     return QRect(); 
    } 
    int columnX = header()->sectionViewportPosition(column); 
    int columnY = visualItemRect(topLevelItem(0)).top(); 
    int columnWidth = header()->sectionSize(column); 
    int columnHeight = visualItemRect(topLevelItem(itemCount-1)).bottom() - columnY + 1; 

    return QRect(columnX, columnY, columnWidth, columnHeight); 
} 

void TreeWidget::repositionColumnWidget() 
{ 
    mColumnWidget->setGeometry(columnRect(3)); 
} 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    a.setQuitOnLastWindowClosed(true); 

    TreeWidget treeWidget; 

    treeWidget.resize(800, 600); 
    treeWidget.show(); 

    return a.exec(); 
} 

#include "main.moc" 
+0

У вас есть некоторые недостающие #includes, и я получаю некоторые другие ошибки, связанные с вызовами connect(). Я на Qt5, вы на какой-то другой версии? – waddlesplash

+0

Я использую Qt 4.8.3 здесь –

+0

Все еще, не должно быть сложно скомпилировать. Работает ли он с Qt5? Однако 'mColumnWidget-> raise()' не был необходим. –

Смежные вопросы