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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Использование Qt виджетов в C#  (Прочитано 2966 раз)
kern32
Гость
« : Апрель 16, 2013, 21:34 »

Доброго времени суток
Встала задача использования уже написанного Qt приложения в уже написанном на C# приложении Улыбающийся
В примерах Qt есть сампл c:\Qt\4.7.1\examples\activeqt\dotnet\wrapper\. В нем все понятно и никаких вопросов не возникает.
Далее создал новый проект на C# с одним единственным окном.  Модифицировал либу из примера "wrapper", в которой попытался создать в отдельном потоке QApplication и QFrame. После запуска приложения у меня есть 2 окна - C# и QFrame.
Можно ли теперь как-то эти окна связать, чтобы мой QFrame был дочерним окном окна C#?

Как это сделать через ActiveQt вроде понятно, но хотелось бы через враппер, если это вообще возможно. Опыта с C# до сегодняшнего дня не было, так что буду признателен за любые подсказки.

Заранее спасибо.

Worker.cpp
Код
C++ (Qt)
 
Worker::Worker()
: frame(NULL)
{
((QThread*)this)->start(QThread::NormalPriority);
}
 
Worker::~Worker()
{
exit();
wait();
}
 
void Worker::run()
{
QApplication app(argc, argv);
app.setQuitOnLastWindowClosed(false);
frame = new QFrame();
frame->show();
app.exec();
}
 
 

Worker.h
Код
C++ (Qt)
 
class Worker : public QThread
{
   Q_OBJECT
public:
   Worker();
   ~Worker();
 
protected:
virtual void run();
 
private:
QFrame *frame;
};
 

Program.cs
Код
C#
       [STAThread]
       static void Main()
       {
           Application.EnableVisualStyles();
           Application.SetCompatibleTextRenderingDefault(false);
           Form1 form = new Form1();
 
           netWorker worker = new netWorker();
 
           Application.Run(form);
       }
Записан
kern32
Гость
« Ответ #1 : Апрель 17, 2013, 09:10 »

Нашел следующее решение для своей проблемы. Не знаю насколько оно корректно, но может кому-то пригодится или как-то поможет.

В коде C# взял хендл окна и передал его в Qt либу.
Код
C#
System.IntPtr hwnd = form.Handle;
netWorker worker = new netWorker(hwnd);
 

далее создал класс унаследованный от QFrame с одной единственной целью, чтобы объявить в нем слот для обновления геометрии:
Код
C++ (Qt)
void MyFrame::updateGeometry( QRect newRect )
{
setGeometry(newRect.x(), newRect.y(), newRect.width(), newRect.height());
}
 

Далее в потоковой функции заюзал виндовый SetParent(pFrame->winId(), m_hwnd). Получилось след. образом:
Код
C++ (Qt)
void Worker::run()
{
int argc = 0;
QApplication app(argc, 0);
app.setQuitOnLastWindowClosed(false);
pFrame = new MyFrame();
pFrame->setWindowFlags(Qt::FramelessWindowHint);
pFrame->setStyleSheet("QFrame{background-color:red;}");
pFrame->show();
 
HWND newHdns = SetParent(pFrame->winId(), m_hwnd);
connect(this, SIGNAL(geometryChanged(QRect)), pFrame, SLOT(updateGeometry(QRect)));
 
app.exec();
}

Далее чтобы Qt виджет изменял свои размеры в соответствии с родительский C# окном, переопределил Resize event
Код
C#
private void Form1_Resize(object sender, EventArgs e)
{
    System.Windows.Forms.Form form = (System.Windows.Forms.Form)sender;
    m_worker.set_Geometry(0, 0, form.ClientSize.Width, form.ClientSize.Height);
}
 
где m_worker это инстанс класса обертки netWorker.

Далее новые размеры передаются в класс Worker, который эмитит сигнал geometryChanged(QRect):
Код
C++ (Qt)
void Worker::setGeometry(int x, int y, int width, int height)
{
rect.setCoords(x, y, width, height);
emit geometryChanged(rect);
}

Вот собственно и все. Какие-либо комментарии по данной имплементации приветствуются Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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