gtkmm 拖放 - 如何在拖动动作事件中将消息从拖动源传递到放置目标?

问题描述 投票:0回答:0

我想要一个 gtkmm 拖放目标,以便在拖放发生之前根据来自源的数据做出决定。是否可以从“拖动动作”回调中请求数据?我在文档中看到了它的提示,但没有明确的例子。

signal_drag_data_received 的 gtkmm 3.24 文档

signal_drag_data_received() 信号在拖拽数据被接收到时在放置点发出。如果接收到数据以确定是否接受放置,则处理程序应调用 gdk_drag_status() 并且不完成拖动。

好像在暗示可以在drop之前请求数据。但我不确定这是否可能或如何去做。以下是连接了

signal_drag_data_get
signal_drag_data_received
signal_drag_motion
信号的拖放的工作示例。

main.cpp

#include <gtkmm.h>
#include "test_window.h"

int
main (int    argc,
      char **argv)
{
   int result = 0;
   argc = 1;
   Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.gtkmm.test_app");
   app->set_flags(Gio::APPLICATION_NON_UNIQUE);
   test_window test_window_i;
   result = app->run(test_window_i);

   return result;
}

test_window.h

#ifndef SRC_TEST_WINDOW_H_
#define SRC_TEST_WINDOW_H_
#include <gtkmm.h>

class test_window: public Gtk::Window
{
public:
   test_window();

   void source_get_data(
                const Glib::RefPtr<Gdk::DragContext>& context,
                Gtk::SelectionData& selection_data,
                guint info,
                guint time);

   void destination_received_data(
                        const Glib::RefPtr<Gdk::DragContext>& context,
                        int x,
                        int y,
                        const Gtk::SelectionData & selection_data,
                        guint info,
                        guint time);

   bool destination_drag_motion_event(
                   const Glib::RefPtr<Gdk::DragContext>& context,
                   int x,
                   int y,
                   guint time);

private:
   Gtk::Box m_box;
   Gtk::Button m_source;
   Gtk::Button m_destination;    
};
#endif

test_window.cpp

#include "test_window.h"
#include <iostream>

test_window::test_window()
{
   show_all();

   set_border_width(1);

   set_type_hint(Gdk::WINDOW_TYPE_HINT_NORMAL);
   resize(800, 800);
   add(m_box);

   m_box.set_orientation(Gtk::ORIENTATION_VERTICAL);
   m_box.pack_start(m_source, true,  false);
   m_box.pack_start(m_destination, true,  false);

   m_source.set_label("source");
   m_destination.set_label("destination");

   std::vector<Gtk::TargetEntry> drag_targets = {
                                        Gtk::TargetEntry("STRING"),
                                        Gtk::TargetEntry("text/plain")};

   m_source.drag_source_set(drag_targets);
   m_destination.drag_dest_set(drag_targets);

   m_source.signal_drag_data_get().connect(sigc::mem_fun(*this, &test_window::source_get_data));
   m_destination.signal_drag_data_received().connect(sigc::mem_fun(*this, &test_window::destination_received_data));
   m_destination.signal_drag_motion ().connect(sigc::mem_fun(*this, &test_window::destination_drag_motion_event));

   show_all();
}

void test_window::source_get_data(
                         const Glib::RefPtr<Gdk::DragContext>& context,
                         Gtk::SelectionData& selection_data,
                         guint info,
                         guint time)
{
   std::string source_message = "Hello from source.";

   selection_data.set(
                   selection_data.get_target(),
                   8 /* 8 bits format */,
                   (const guchar*)source_message.c_str(),
                   source_message.size());
}

void test_window::destination_received_data(
                           const Glib::RefPtr<Gdk::DragContext>& context,
                           int x,
                           int y,
                           const Gtk::SelectionData & selection_data,
                           guint info,
                           guint time)
{
   if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
   {
      std::string message = selection_data.get_data_as_string();
      std::cout << message << std::endl;
   }

   context->drag_finish(false, false, time);
}

bool test_window::destination_drag_motion_event(
                               const Glib::RefPtr<Gdk::DragContext>& context,
                               int x,
                               int y,
                               guint time)
{
   std::cout << "Destination drag motion event." << std::endl;    
   return true;
}

制作文件

EXECUTABLE=test_app
CFLAGS=-c -Wall -g 

CC=g++
# 
SOURCES= src/main.cpp src/test_window.cpp
OBJECTS=$(SOURCES:.cpp=.o)

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS) 
    $(CC) $(OBJECTS) -o $@ `pkg-config gtkmm-3.0 --libs` 

.cpp.o:
    $(CC) $(CFLAGS) $< -o $@ `pkg-config gtkmm-3.0 --cflags` 

clean:
    rm -rf src/*.o  $(EXECUTABLE)
gtk gtk3 gtkmm
© www.soinside.com 2019 - 2024. All rights reserved.