2012-07-04 31 views
5

Tôi đang triển khai chế độ xem và mô hình mà tôi muốn hỗ trợ cả các mục di chuyển trong nội bộ (bằng cách kéo) và sao chép các mục (bằng cách nhấn Ctrl trong khi kéo). Tôi đã làm mọi thứ tôi cần làm theo hướng dẫn. Tôi đã thiết lập các hàm mime, tôi đã thực hiện removeRows() và flags(). Vấn đề là khi tôi kéo, nó mặc định cho một hoạt động sao chép (tôi nhận được con trỏ mũi tên với một dấu cộng, và nó thực sự sao chép các mục bằng cách tạo ra một cái mới trong mô hình).Kéo/thả Qt: không thể di chuyển khi sao chép được bật (Ubuntu Gnome)

Sự khác biệt duy nhất tôi có thể thấy là: Nếu tôi chỉ trả về Qt :: MoveAction trong supportDropActions(), nó chỉ di chuyển. Nếu tôi quay trở lại (Qt :: CopyAction | Qt :: MoveAction), nó chỉ sao chép.

Bất kỳ ý tưởng nào? Tôi muốn nó hoạt động giống như các tập tin trong Nautilus (Gnome) hoặc Windows file Explorer: kéo di chuyển các biểu tượng xung quanh, ctrl + kéo bản sao chúng.

+0

Vấn đề tương tự cũng xảy ra trên Windows, nhưng với 'Qt :: MoveAction' là lựa chọn ưu tiên. –

+0

Tôi có thể đăng một số mã ví dụ để chứng minh sự cố, nếu có ai muốn. –

+0

Vì điều này đã không trả lời câu hỏi của tôi cuối cùng, những người cảm thấy họ xứng đáng với tiền thưởng? –

Trả lời

0

gì xảy ra nếu bạn cố gắng theo cách này đầu tiên viết một keyPressEvent và thiết lập cho dù phím Ctrl được nhấn hay không '

keyPressEvent(QKeyEvent *e) 
    { 
     if(e->key() == Qt::Key_Control) 
      bControlKeyPressed = true; 
    } 
    keyReleaseEvent (QKeyEvent *e) 
    { 
     if(e->key() == Qt::Key_Control) 
      bControlKeyPressed = false; 
    } 

Và trong chuột pressEvent kiểm tra xem phím Ctrl được nhấn

`mousePressEvent() 
{ 
    if (bControlKeyPressed) 
    //enable Qt::CopyAction 
else 
    //enable Qt::MoveAction 
}` 
+0

Câu trả lời đơn giản vì đây sẽ là lý tưởng , nhưng Ubuntu/Windows chỉ bỏ qua hành động được chỉ định (và hành động mặc định). –

0

Đây là những gì tôi sẽ làm:

bật hành động sao chép. Sau đó nghe các tín hiệu thả xuống & drap hoặc ghi đè lên các phương thức ảo (hoặc bất kỳ ưu đãi Qt nào, tôi không kiểm tra) và nếu hành động bạn muốn di chuyển, hãy xóa hàng "thủ công". Khi một thả được thực hiện, lưu các hành động mà bạn thích.

Nếu không có cách nào để xác định hành động mong muốn từ dữ liệu Qt, hãy kiểm tra trạng thái khóa Ctrl và lưu một boolean cho biết đó là bản sao hay di chuyển. Bây giờ, khi tín hiệu Qt đã bị xóa, hãy kiểm tra hành động bạn đã chọn và tự xóa hàng đã di chuyển.

(cá nhân tôi sử dụng gtkmm, nơi tác phẩm sao chép if-Ctrl-được-ép pefectly)

+0

Giải pháp này có phần hoạt động nhưng có hai vấn đề: a) Biểu tượng kéo không chính xác. b) Nếu một số mục được chọn, kéo chúng giữa chúng sẽ xóa một số và sao chép các mục khác. –

+0

Sau đó, tôi thấy hai tùy chọn cho bạn. 1) Cách tiếp cận đơn giản: Đặt biểu tượng theo cách thủ công. Đối với nhiều lựa chọn, hãy tự mình xử lý. Quyết định cách di chuyển/sao chép từng nút. Nó có thể phức tạp, tùy thuộc vào cách Qt cho phép bạn truy cập dữ liệu kéo và thả ... 2) phương pháp tiếp cận kỹ sư nghiêm túc: tìm hiểu lý do tại sao điều này không hoạt động như mong muốn. Qt là phần mềm miễn phí, vì vậy nếu có lỗi, hãy điều tra xem liệu nó có thể được giải quyết hay không. Vì vậy, bạn đóng góp cho tất cả người dùng của Qt và bất kỳ ứng dụng nào được viết bằng Qt. Và không có cách giải quyết nào cần thiết. – cfa45ca55111016ee9269f0a52e771

+0

Nếu có vấn đề với Windows internals, tốt nhất bạn có thể làm là gửi cho họ một e-mail. Windows là phần mềm sở hữu độc quyền nên tôi coi đó là vấn đề của họ, không phải của tôi hay của bạn, nếu D & D không hoạt động như nó cần. Hoặc thêm một giải pháp tạm thời trong mã của bạn, chỉ cho Windows – cfa45ca55111016ee9269f0a52e771

1

Tôi xin lỗi tôi đã không theo dõi bằng cách trả lời câu hỏi này khi tôi tìm thấy những gì tôi đang làm sai. Mã mà sai lầm tôi đã ở QAbstractItemView::startDrag():

if (d->defaultDropAction != Qt::IgnoreAction && (supportedActions & d->defaultDropAction)) 
     defaultDropAction = d->defaultDropAction; 
    else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove) 
     defaultDropAction = Qt::CopyAction; 

Vấn đề là tôi đã không thiết lập các defaultDropAction tài sản trên widget như trong setDefaultDropAction(Qt::MoveAction); Do đó startDrag() đã được mặc định cho CopyAction. Nếu defaultDropAction là Qt :: MoveAction, thì bạn có thể sử dụng bàn phím Ctrl để chuyển một tiến trình kéo sang hành động sao chép, đó là hành vi mong muốn của tôi.

Tôi thích Qt, nhưng chắc chắn có rất nhiều thuộc tính khó hiểu và phần nào đan xen liên quan đến kéo/thả. Thật dễ dàng để không có được sự kết hợp đúng đắn của các thuộc tính.

Dòng dưới cùng: đảm bảo đặt defaultDropAction thành Qt :: MoveAction.

+0

Chỉ cần cung cấp thêm một chút thông tin, các thuộc tính mà tôi đã thay đổi trên listView như sau: acceptDrops: true, dragEnabled: true, defaultDropAction: MoveAction (đây là một!), selectionMode: ExtendedSelection (cũng là một hành vi Windows Explorer dự kiến ​​nhưng không phải là mặc định cho QListView). Cũng trong mô hình: setSupportedDragActions (Qt :: CopyAction | Qt :: MoveAction) ;, trả về Qt :: CopyAction | Qt :: MoveAction trong MyModel :: Model :: supportedDropActions(), thêm Qt :: ItemIsDragEnabled vào MyModel :: flags(), triển khai MyModel :: mimeTypes(), mimeData() và dropMimeData. Hy vọng rằng sẽ giúp! – Scott

+0

Điều này có nghĩa là lỗi mà tôi đang trải nghiệm thực sự khác với lỗi bạn gặp phải. Nó trông giống như một lỗi Qt trên Windows. –

+0

D K, tôi tò mò - nó là một Qt SDK (Creator) mà là * thường * mingw dựa, hoặc là nó Qt biên dịch với Visual Studio (mà là dựa trên WinAPI?). Ngoài ra, vấn đề của tôi là, với Sao chép là hành vi mặc định, tôi không thể đạt được Di chuyển chút nào, bởi vì không có công cụ sửa đổi bàn phím nào để thay đổi Sao chép thành Di chuyển. Bạn nói rằng bạn đang gặp vấn đề với Di chuyển - vì vậy bạn không thể giữ Ctrl và thay đổi nó thành Sao chép? – Scott

Các vấn đề liên quan