Russian Qt Forum
Ноябрь 23, 2024, 19:30 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 2 [3]   Вниз
  Печать  
Автор Тема: Буфер обмена и самодельные типы данных  (Прочитано 27260 раз)
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #30 : Ноябрь 17, 2008, 00:18 »

Лениво сейчас все расписывать. И я так понимаю, что С++ тебе не очень то интересен.

Неправильно понимаешь. http://www.gamedev.ru/community/experimentalgameplay/forum/?id=75236, раздел "Производные цели", четвертый пункт.
Записан

Собираю информацию по крупицам
http://webhamster.ru
BRE
Гость
« Ответ #31 : Ноябрь 17, 2008, 00:30 »

Лениво сейчас все расписывать. И я так понимаю, что С++ тебе не очень то интересен.

Неправильно понимаешь. http://www.gamedev.ru/community/experimentalgameplay/forum/?id=75236, раздел "Производные цели", четвертый пункт.
Это я после это твоей фразы
Цитировать
Поэтому я и нелюблю C/C++, но приходится прогать на нем, ибо альтернатив нет.

Qt != С++.
Скажу даже больше, Qt навязывает определенные правила программирования. Как бы стереотипы. Попробуй решить задачу на C++ без использования Qt. Но решить не просто так, что мне нужен вектор объектов, поэтому нужно написать класс Vector. А самому определить сущности, заставить их взаимодействовать...
В это весь кайф.  Подмигивающий
Записан
Tonal
Гость
« Ответ #32 : Ноябрь 20, 2008, 08:59 »

От всё бы вам холиварить, горячие эстонские парни! Улыбающийся

По поводу Урока есть небольшое дополнение:
Передача данных через QByteArray и setData() отличается от передачи через QByteArray и retrieveData().
Различие заключается в том, что в первом случае придётся перегонять данные в QByteArray и отдавать сразу, а во втором, только тогда, когда пользователь их запросил - тогда и вызывается retrieveData().
Это может быть критично, например, для очень больших объектов или для случаев, когда данные часто изменяются, и ты хочешь скопировать 1 раз, а вставлять всегда наиболее свежее состояние. Улыбающийся

Случаи 2 и 3 из первого поста, отличаются тем, что если передача данных идёт гарантировано в рамках одного процесса, то ты можешь после получения QMimeDada из клипборда просто привести его к реальному типу и дальше работать с ним через дополнительно определённые методы и свойства, совсем не связываясь с QVariant-ом и прочими QByteArray-ями, а работая просто через указатели и ссылки. Улыбающийся
Но если передача идёт между разными экземплярами, то данные придётся передавать между процессами. К тому же в принимающем процессе Qt создаст экземпляр стандартного QMimeDada а не твоего наследника.
Записан
vaprele07
Гость
« Ответ #33 : Ноябрь 20, 2008, 13:24 »

Различие заключается в том, что в первом случае придётся перегонять данные в QByteArray и отдавать сразу, а во втором, только тогда, когда пользователь их запросил - тогда и вызывается retrieveData()
как они могут отдаваться сразу... потом, если они копируются в системный буфер, предварительно принимая определенный вид... мне не понятно Непонимающий
по поводу больших передаче больших объектов через буфер обмена... так это вообще глупо Строит глазки
Записан
Tonal
Гость
« Ответ #34 : Ноябрь 24, 2008, 22:55 »

В системный буфер отдаётся список форматов и калбек. По крайней мере в WinApi такое есть, думаю и в Х-ах тоже.
Насчёт больших объёмов - а какие считать большими? И что делать если таки больше?

Например страница сайта - это много или мало? Или отчётик екселевский?
И что делать простому юзеру ежели ему это в свой документ какой вставить нужно?
Сможешь всем объяснить? Улыбающийся
Записан
vaprele07
Гость
« Ответ #35 : Ноябрь 25, 2008, 03:55 »

знаю что в кде3-4 твои калбеки здорово работают при закрытии проги теряешь буфер. если конечно у тебе не загружен кклипбоард в винде проще там есть оле-объекты.

в любом случае калбек не калбек... копию данных в момент копирования придется сделать!
и все равно оно в итоге преобразуется в байтарей! по этому желательно сразу перегнать все в байтарей и отдать в буфер без всяких заморочек. посмотрел исходники кутэ и убедился в своей правоте Улыбающийся хотя мог чего не доглядеть...
Записан
Tonal
Гость
« Ответ #36 : Ноябрь 26, 2008, 09:02 »

Оле объекты тут не при чём.
Если используешь этот механизм, то при закрытии программы или всё потеряется, или нужно перегнать в нужные форматы и скормить их клипборду.
Тот же мсворд, если выделить и скопировать много данных, при закрытии спрашивает что с ними делать.

Так что техника есть, Qt её поддерживает, случаи применения я указал, а применять её или нет - каждый решает сам. Улыбающийся
Записан
vaprele07
Гость
« Ответ #37 : Ноябрь 26, 2008, 12:41 »

какой механизм? я же написал... смотрел исходники кутэ... ничего подобного не увидел о чем ты тут рассказывал... мне просто интересно где ты эти знания взял (в контексте кутэ)
а именно:
Цитата: Tonal
а во втором, только тогда, когда пользователь их запросил - тогда и вызывается retrieveData()
Записан
Tonal
Гость
« Ответ #38 : Ноябрь 27, 2008, 14:54 »

Ну, я как бы и не сомнивался в этом механизме. Улыбающийся
Сделал, когда потребовалось, полагаясь на него, и оно работает.
Код
Python
# -*- coding: cp1251 -*-
#file aaa.py
 
import sys
from PyQt4 import QtCore, QtGui
 
class _MimeData(QtCore.QMimeData):
 u"Класс поддержки клипбоарда"
 format_templ = u'application/x-python-mime;value="%s"'
 obj = None
 format_name = ''
 def __init__(self, obj):
   super(_MimeData, self).__init__()
   self.obj = obj
   self.format_name = self.format_templ % obj.__class__.__name__
 
 def hasFormat(self, mimetype):
   if mimetype in (self.format_name, u'text/plain'):
     return True
   return QtCore.QMimeData.hasFormat(self, mimetype)
 
 def formats(self):
   base_formats = QtCore.QMimeData.formats(self)
   return list(set(list(base_formats) + [self.format_name, u'text/plain']))
 
 def retrieveData(self, mimetype, preferredType):
   print 'retrieveData(%s, %s)' %(mimetype, preferredType)
   if mimetype == self.format_name:
     return QtCore.QVariant(self.obj)
   if mimetype == u'text/plain':
     return QtCore.QVariant(u'%s' % self.obj)
   return QtCore.QMimeData.retrieveData(self, mimetype, preferredType)
 
def main():
 app = QtGui.QApplication(sys.argv)
 print 'copy data to clipboard'
 data1 = _MimeData(['aaa', 'bbb', 'ccc'])
 QtGui.QApplication.clipboard().setMimeData(data1)
 print 'paste data from clipboard'
 data2 = QtGui.QApplication.clipboard().mimeData()
 text = data2.text()
 print text
 
if __name__ == '__main__':
 main()
 
Протокол запуска под виндой:
Код:
C:\Lang>aaa.py
copy data to clipboard
paste data from clipboard
retrieveData(text/plain, 10)
['aaa', 'bbb', 'ccc']
Как видишь, вызовы происходят именно в описываемом мною порядке.
Хотя на linux-е не проверял - приду домой - проверю. Улыбающийся

Ну и в ассистенте про retrieveData написано:
Цитировать
This function is called by the general data() getter and by the convenience getters (text(), html(), urls(), imageData(), and colorData()).
Т.е. пока не вызвана одна из перечисленных функций, retrieveData не дёрнется.
При вызове QClipboard::setMimeData в винде таковые не вызываются.

П.С. Действительно, виндовская реализация работает через COM (хотя это и не обязательно).
Записан
vaprele07
Гость
« Ответ #39 : Ноябрь 27, 2008, 15:28 »

не ну это не интересно... а ты пробовал получать свои данные в контексте другой программы?  Шокированный
Записан
Tonal
Гость
« Ответ #40 : Ноябрь 28, 2008, 18:38 »

Да, на винде вполне работает.
Под *nux ещё не проверял, но если верить документации, то должно. Улыбающийся
Записан
vaprele07
Гость
« Ответ #41 : Ноябрь 29, 2008, 03:44 »

блин ты не догнал %) сделай небольшое изменение примеру
после последнего print text
Код
Python
widget = QtGui.QTextEdit()
widget.show()
app.exec_()
 

да здорово в едитор можно вставить твои 'aaa', 'bbb', 'ccc'
а теперь открой, не закрывая окна своей проги, любую другую прогу и попробуй получить данные из буфера...  Смеющийся  т.е. данных твоих в буффере нет!... не понимаю как может одна функция retrievData работать одновременно и на прием и на передачу...

а еще наглядней запусти две копии твоей проги с моим изменением, исправив во второй 'aaa', 'bbb', 'ccc' на 'xxx', 'yyy', 'zzz'

проверял под убунту%)
Записан
Tonal
Гость
« Ответ #42 : Декабрь 01, 2008, 11:17 »

У меня данные в буфере есть, и любая прога ожидающая text/plain их видит пока тест запущен.

Судя по тому, к чему приводят твои эксперименты, для linux-а этот механизм просто не работает.
Это либо баг/недоделка, либо кривость документации, т.к. там ничего подобного не упомянуто.

Подкорректировал и разделил на 2 проги.
Вот вывод первой:
Код:
C:\Lang\test\python\qtClipb>aaa.py
2008-12-01 14:04:22.971000 copy data to clipboard
!>2008-12-01 14:04:29.148000 retrieveData(text/plain, 10)

2008-12-01 14:04:34.668000 paste data from clipboard
2008-12-01 14:04:34.668000 retrieveData(text/plain, 10)
['aaa', 'bbb', 'ccc']
Вот вывод второй:
Код:
C:\Lang\test\python\qtClipb>bbb.py
2008-12-01 14:04:29.123000 paste data from clipboard
2008-12-01 14:04:29.150000 ['aaa', 'bbb', 'ccc']
Обрати внимание на время.

Вот полный код обоих частей:
Код
Python
# -*- coding: cp1251 -*-
#file aaa.py
import sys
from datetime import datetime
from PyQt4 import QtCore, QtGui
 
#Работа с клипбоардом.
class _MimeData(QtCore.QMimeData):
 u"Класс поддержки клипбоарда"
 format_templ = u'application/x-python-mime;value="%s"'
 obj = None
 format_name = ''
 def __init__(self, obj):
   super(_MimeData, self).__init__()
   self.obj = obj
   self.format_name = self.format_templ % obj.__class__.__name__
 
 def hasFormat(self, mimetype):
   if mimetype in (self.format_name, u'text/plain'):
     return True
   return QtCore.QMimeData.hasFormat(self, mimetype)
 
 def formats(self):
   base_formats = QtCore.QMimeData.formats(self)
   return list(set(list(base_formats) + [self.format_name, u'text/plain']))
 
 def retrieveData(self, mimetype, preferredType):
   print '%s retrieveData(%s, %s)' %(datetime.now(), mimetype, preferredType)
   if mimetype == self.format_name:
     return QtCore.QVariant(self.obj)
   if mimetype == u'text/plain':
     return QtCore.QVariant(u'%s' % self.obj)
   return QtCore.QMimeData.retrieveData(self, mimetype, preferredType)
 
def main():
 app = QtGui.QApplication(sys.argv)
 print datetime.now(), 'copy data to clipboard'
 data1 = _MimeData(['aaa', 'bbb', 'ccc'])
 QtGui.QApplication.clipboard().setMimeData(data1)
 raw_input('!>')
 print datetime.now(), 'paste data from clipboard'
 data2 = QtGui.QApplication.clipboard().mimeData()
 text = data2.text()
 print text
 
if __name__ == '__main__':
 main()
 

Код
Python
# -*- coding: cp1251 -*-
#file bbb.py
import sys
from datetime import datetime
from PyQt4 import QtCore, QtGui
 
def main():
 app = QtGui.QApplication(sys.argv)
 print datetime.now(), 'paste data from clipboard'
 data2 = QtGui.QApplication.clipboard().mimeData()
 text = data2.text()
 print datetime.now(), text
 
if __name__ == '__main__':
 main()
 
Записан
Страниц: 1 2 [3]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.107 секунд. Запросов: 22.